| 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
|
| deleted file mode 100644
|
| index 7ca3eb7a7290131ac0b576c71597e6c402830886..0000000000000000000000000000000000000000
|
| --- a/content/renderer/scheduler/renderer_scheduler_impl.cc
|
| +++ /dev/null
|
| @@ -1,641 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "content/renderer/scheduler/renderer_scheduler_impl.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/message_loop/message_loop_proxy.h"
|
| -#include "base/trace_event/trace_event.h"
|
| -#include "base/trace_event/trace_event_argument.h"
|
| -#include "cc/output/begin_frame_args.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)
|
| - : helper_(main_task_runner,
|
| - this,
|
| - "renderer.scheduler",
|
| - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerIdlePeriod",
|
| - TASK_QUEUE_COUNT,
|
| - base::TimeDelta()),
|
| - control_task_runner_(helper_.ControlTaskRunner()),
|
| - compositor_task_runner_(
|
| - helper_.TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
|
| - loading_task_runner_(helper_.TaskRunnerForQueue(LOADING_TASK_QUEUE)),
|
| - timer_task_runner_(helper_.TaskRunnerForQueue(TIMER_TASK_QUEUE)),
|
| - delayed_update_policy_runner_(
|
| - base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| - base::Unretained(this)),
|
| - helper_.ControlTaskRunner()),
|
| - current_policy_(Policy::NORMAL),
|
| - renderer_hidden_(false),
|
| - last_input_type_(blink::WebInputEvent::Undefined),
|
| - input_stream_state_(InputStreamState::INACTIVE),
|
| - policy_may_need_update_(&incoming_signals_lock_),
|
| - timer_queue_suspend_count_(0),
|
| - weak_factory_(this) {
|
| - update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
|
| - weak_factory_.GetWeakPtr());
|
| - end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
|
| - &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
|
| -
|
| - for (size_t i = SchedulerHelper::TASK_QUEUE_COUNT;
|
| - i < TASK_QUEUE_COUNT;
|
| - i++) {
|
| - helper_.SetQueueName(i, TaskQueueIdToString(static_cast<QueueId>(i)));
|
| - }
|
| - TRACE_EVENT_OBJECT_CREATED_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| - this);
|
| -}
|
| -
|
| -RendererSchedulerImpl::~RendererSchedulerImpl() {
|
| - TRACE_EVENT_OBJECT_DELETED_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| - this);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::Shutdown() {
|
| - helper_.Shutdown();
|
| -}
|
| -
|
| -scoped_refptr<base::SingleThreadTaskRunner>
|
| -RendererSchedulerImpl::DefaultTaskRunner() {
|
| - return helper_.DefaultTaskRunner();
|
| -}
|
| -
|
| -scoped_refptr<base::SingleThreadTaskRunner>
|
| -RendererSchedulerImpl::CompositorTaskRunner() {
|
| - helper_.CheckOnValidThread();
|
| - return compositor_task_runner_;
|
| -}
|
| -
|
| -scoped_refptr<SingleThreadIdleTaskRunner>
|
| -RendererSchedulerImpl::IdleTaskRunner() {
|
| - return helper_.IdleTaskRunner();
|
| -}
|
| -
|
| -scoped_refptr<base::SingleThreadTaskRunner>
|
| -RendererSchedulerImpl::LoadingTaskRunner() {
|
| - helper_.CheckOnValidThread();
|
| - return loading_task_runner_;
|
| -}
|
| -
|
| -scoped_refptr<base::SingleThreadTaskRunner>
|
| -RendererSchedulerImpl::TimerTaskRunner() {
|
| - helper_.CheckOnValidThread();
|
| - return timer_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());
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown())
|
| - return;
|
| -
|
| - EndIdlePeriod();
|
| - estimated_next_frame_begin_ = args.frame_time + args.interval;
|
| - // TODO(skyostil): Wire up real notification of input events processing
|
| - // instead of this approximation.
|
| - DidProcessInputEvent(args.frame_time);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::DidCommitFrameToCompositor() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerImpl::DidCommitFrameToCompositor");
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown())
|
| - return;
|
| -
|
| - 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)
|
| - 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");
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown())
|
| - return;
|
| -
|
| - // TODO(skyostil): Wire up real notification of input events processing
|
| - // instead of this approximation.
|
| - DidProcessInputEvent(base::TimeTicks());
|
| -
|
| - helper_.EnableLongIdlePeriod();
|
| -}
|
| -
|
| -void RendererSchedulerImpl::OnRendererHidden() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerImpl::OnRendererHidden");
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown() || renderer_hidden_)
|
| - return;
|
| -
|
| - helper_.EnableLongIdlePeriod();
|
| -
|
| - // Ensure that we stop running idle tasks after a few seconds of being hidden.
|
| - end_renderer_hidden_idle_period_closure_.Cancel();
|
| - base::TimeDelta end_idle_when_hidden_delay =
|
| - base::TimeDelta::FromMilliseconds(kEndIdleWhenHiddenDelayMillis);
|
| - control_task_runner_->PostDelayedTask(
|
| - FROM_HERE,
|
| - end_renderer_hidden_idle_period_closure_.callback(),
|
| - end_idle_when_hidden_delay);
|
| - renderer_hidden_ = true;
|
| -
|
| - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| - this, AsValueLocked(helper_.Now()));
|
| -}
|
| -
|
| -void RendererSchedulerImpl::OnRendererVisible() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerImpl::OnRendererVisible");
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown() || !renderer_hidden_)
|
| - return;
|
| -
|
| - end_renderer_hidden_idle_period_closure_.Cancel();
|
| - renderer_hidden_ = false;
|
| - EndIdlePeriod();
|
| -
|
| - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
|
| - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
|
| - this, AsValueLocked(helper_.Now()));
|
| -}
|
| -
|
| -void RendererSchedulerImpl::EndIdlePeriod() {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerImpl::EndIdlePeriod");
|
| - helper_.CheckOnValidThread();
|
| - helper_.EndIdlePeriod();
|
| -}
|
| -
|
| -void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread(
|
| - const blink::WebInputEvent& web_input_event) {
|
| - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
| - "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread");
|
| - // We regard MouseMove events with the left mouse button down as a signal
|
| - // that the user is doing something requiring a smooth frame rate.
|
| - if (web_input_event.type == blink::WebInputEvent::MouseMove &&
|
| - (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) {
|
| - UpdateForInputEvent(web_input_event.type);
|
| - return;
|
| - }
|
| - // Ignore all other mouse events because they probably don't signal user
|
| - // interaction needing a smooth framerate. NOTE isMouseEventType returns false
|
| - // for mouse wheel events, hence we regard them as user input.
|
| - // Ignore keyboard events because it doesn't really make sense to enter
|
| - // compositor priority for them.
|
| - if (blink::WebInputEvent::isMouseEventType(web_input_event.type) ||
|
| - blink::WebInputEvent::isKeyboardEventType(web_input_event.type)) {
|
| - return;
|
| - }
|
| - UpdateForInputEvent(web_input_event.type);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::DidAnimateForInputOnCompositorThread() {
|
| - UpdateForInputEvent(blink::WebInputEvent::Undefined);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::UpdateForInputEvent(
|
| - blink::WebInputEvent::Type type) {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| -
|
| - InputStreamState new_input_stream_state =
|
| - ComputeNewInputStreamState(input_stream_state_, type, last_input_type_);
|
| -
|
| - if (input_stream_state_ != new_input_stream_state) {
|
| - // Update scheduler policy if we should start a new policy mode.
|
| - input_stream_state_ = new_input_stream_state;
|
| - EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
|
| - }
|
| - 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
|
| - // called before the input event is processed either on the compositor or
|
| - // main threads.
|
| - last_input_process_time_on_main_ = base::TimeTicks();
|
| - last_input_type_ = type;
|
| -}
|
| -
|
| -void RendererSchedulerImpl::DidProcessInputEvent(
|
| - base::TimeTicks begin_frame_time) {
|
| - helper_.CheckOnValidThread();
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| - if (input_stream_state_ == InputStreamState::INACTIVE)
|
| - return;
|
| - // Avoid marking input that arrived after the BeginFrame as processed.
|
| - if (!begin_frame_time.is_null() &&
|
| - begin_frame_time < last_input_receipt_time_on_compositor_)
|
| - return;
|
| - last_input_process_time_on_main_ = helper_.Now();
|
| - UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
|
| -}
|
| -
|
| -bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown())
|
| - return false;
|
| -
|
| - 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;
|
| -}
|
| -
|
| -bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
|
| - helper_.CheckOnValidThread();
|
| - if (helper_.IsShutdown())
|
| - 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 (SchedulerPolicy()) {
|
| - case Policy::NORMAL:
|
| - return false;
|
| -
|
| - case Policy::COMPOSITOR_PRIORITY:
|
| - return !helper_.IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
|
| -
|
| - case Policy::TOUCHSTART_PRIORITY:
|
| - return true;
|
| -
|
| - default:
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -base::TimeTicks
|
| -RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() const {
|
| - base::TimeTicks deadline;
|
| - helper_.CurrentIdleTaskDeadlineCallback(&deadline);
|
| - return deadline;
|
| -}
|
| -
|
| -RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const {
|
| - helper_.CheckOnValidThread();
|
| - return current_policy_;
|
| -}
|
| -
|
| -void RendererSchedulerImpl::MaybeUpdatePolicy() {
|
| - helper_.CheckOnValidThread();
|
| - if (policy_may_need_update_.IsSet()) {
|
| - UpdatePolicy();
|
| - }
|
| -}
|
| -
|
| -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();
|
| - if (!policy_may_need_update_.IsSet()) {
|
| - policy_may_need_update_.SetWhileLocked(true);
|
| - control_task_runner_->PostTask(from_here, update_policy_closure_);
|
| - }
|
| -}
|
| -
|
| -void RendererSchedulerImpl::UpdatePolicy() {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| - UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::ForceUpdatePolicy() {
|
| - base::AutoLock lock(incoming_signals_lock_);
|
| - UpdatePolicyLocked(UpdateType::FORCE_UPDATE);
|
| -}
|
| -
|
| -void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
|
| - helper_.CheckOnValidThread();
|
| - incoming_signals_lock_.AssertAcquired();
|
| - if (helper_.IsShutdown())
|
| - return;
|
| -
|
| - base::TimeTicks now = helper_.Now();
|
| - policy_may_need_update_.SetWhileLocked(false);
|
| -
|
| - 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;
|
| - delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
|
| - now);
|
| - } else {
|
| - current_policy_expiration_time_ = base::TimeTicks();
|
| - }
|
| -
|
| - if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
|
| - new_policy == current_policy_)
|
| - return;
|
| -
|
| - PrioritizingTaskQueueSelector* task_queue_selector =
|
| - helper_.SchedulerTaskQueueSelector();
|
| - bool policy_disables_timers = false;
|
| -
|
| - switch (new_policy) {
|
| - case Policy::COMPOSITOR_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.
|
| - task_queue_selector->SetQueuePriority(
|
| - LOADING_TASK_QUEUE,
|
| - PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
|
| - break;
|
| - case Policy::TOUCHSTART_PRIORITY:
|
| - task_queue_selector->SetQueuePriority(
|
| - COMPOSITOR_TASK_QUEUE, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
|
| - task_queue_selector->DisableQueue(LOADING_TASK_QUEUE);
|
| - // TODO(alexclarke): Set policy_disables_timers once the blink TimerBase
|
| - // refactor is safely landed.
|
| - break;
|
| - case Policy::NORMAL:
|
| - task_queue_selector->SetQueuePriority(
|
| - COMPOSITOR_TASK_QUEUE,
|
| - PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
|
| - task_queue_selector->SetQueuePriority(
|
| - LOADING_TASK_QUEUE, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
|
| - break;
|
| - }
|
| - if (timer_queue_suspend_count_ != 0 || policy_disables_timers) {
|
| - task_queue_selector->DisableQueue(TIMER_TASK_QUEUE);
|
| - } else {
|
| - helper_.SchedulerTaskQueueSelector()->SetQueuePriority(
|
| - TIMER_TASK_QUEUE, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
|
| - }
|
| - DCHECK(task_queue_selector->IsQueueEnabled(COMPOSITOR_TASK_QUEUE));
|
| - if (new_policy != Policy::TOUCHSTART_PRIORITY)
|
| - DCHECK(task_queue_selector->IsQueueEnabled(LOADING_TASK_QUEUE));
|
| -
|
| - 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_);
|
| -}
|
| -
|
| -RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
|
| - base::TimeTicks now,
|
| - base::TimeDelta* new_policy_duration) {
|
| - helper_.CheckOnValidThread();
|
| - incoming_signals_lock_.AssertAcquired();
|
| -
|
| - Policy new_policy = Policy::NORMAL;
|
| - *new_policy_duration = base::TimeDelta();
|
| -
|
| - if (input_stream_state_ == InputStreamState::INACTIVE)
|
| - return new_policy;
|
| -
|
| - Policy input_priority_policy =
|
| - input_stream_state_ ==
|
| - InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE
|
| - ? Policy::TOUCHSTART_PRIORITY
|
| - : Policy::COMPOSITOR_PRIORITY;
|
| - base::TimeDelta time_left_in_policy = TimeLeftInInputEscalatedPolicy(now);
|
| - if (time_left_in_policy > base::TimeDelta()) {
|
| - new_policy = input_priority_policy;
|
| - *new_policy_duration = time_left_in_policy;
|
| - } else {
|
| - // Reset |input_stream_state_| to ensure
|
| - // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task
|
| - // when it's next called.
|
| - input_stream_state_ = InputStreamState::INACTIVE;
|
| - }
|
| - return new_policy;
|
| -}
|
| -
|
| -base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
|
| - base::TimeTicks now) const {
|
| - 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();
|
| -
|
| - base::TimeDelta escalated_priority_duration =
|
| - base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
|
| - base::TimeDelta time_left_in_policy;
|
| - if (last_input_process_time_on_main_.is_null() &&
|
| - !helper_.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;
|
| - } else {
|
| - // Otherwise make sure the input prioritization policy ends on time.
|
| - base::TimeTicks new_priority_end(
|
| - std::max(last_input_receipt_time_on_compositor_,
|
| - last_input_process_time_on_main_) +
|
| - escalated_priority_duration);
|
| - time_left_in_policy = new_priority_end - now;
|
| - }
|
| - return time_left_in_policy;
|
| -}
|
| -
|
| -bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
|
| - base::TimeTicks now,
|
| - base::TimeDelta* next_long_idle_period_delay_out) {
|
| - 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 false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() {
|
| - return &helper_;
|
| -}
|
| -
|
| -void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
|
| - helper_.SetWorkBatchSizeForTesting(work_batch_size);
|
| -}
|
| -
|
| -RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
|
| - base::Lock* write_lock_)
|
| - : flag_(false), write_lock_(write_lock_) {
|
| -}
|
| -
|
| -RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() {
|
| -}
|
| -
|
| -void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetWhileLocked(
|
| - bool value) {
|
| - write_lock_->AssertAcquired();
|
| - base::subtle::Release_Store(&flag_, value);
|
| -}
|
| -
|
| -bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
|
| - return base::subtle::Acquire_Load(&flag_) != 0;
|
| -}
|
| -
|
| -void RendererSchedulerImpl::SuspendTimerQueue() {
|
| - helper_.CheckOnValidThread();
|
| - timer_queue_suspend_count_++;
|
| - ForceUpdatePolicy();
|
| - DCHECK(!helper_.SchedulerTaskQueueSelector()->IsQueueEnabled(
|
| - TIMER_TASK_QUEUE));
|
| -}
|
| -
|
| -void RendererSchedulerImpl::ResumeTimerQueue() {
|
| - helper_.CheckOnValidThread();
|
| - timer_queue_suspend_count_--;
|
| - DCHECK_GE(timer_queue_suspend_count_, 0);
|
| - ForceUpdatePolicy();
|
| -}
|
| -
|
| -// static
|
| -const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
|
| - switch (queue_id) {
|
| - case COMPOSITOR_TASK_QUEUE:
|
| - return "compositor_tq";
|
| - case LOADING_TASK_QUEUE:
|
| - return "loading_tq";
|
| - case TIMER_TASK_QUEUE:
|
| - return "timer_tq";
|
| - default:
|
| - return SchedulerHelper::TaskQueueIdToString(
|
| - static_cast<SchedulerHelper::QueueId>(queue_id));
|
| - }
|
| -}
|
| -
|
| -// static
|
| -const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
|
| - switch (policy) {
|
| - case Policy::NORMAL:
|
| - return "normal";
|
| - case Policy::COMPOSITOR_PRIORITY:
|
| - return "compositor";
|
| - case Policy::TOUCHSTART_PRIORITY:
|
| - return "touchstart";
|
| - default:
|
| - NOTREACHED();
|
| - return nullptr;
|
| - }
|
| -}
|
| -
|
| -const char* RendererSchedulerImpl::InputStreamStateToString(
|
| - InputStreamState state) {
|
| - switch (state) {
|
| - case InputStreamState::INACTIVE:
|
| - return "inactive";
|
| - case InputStreamState::ACTIVE:
|
| - return "active";
|
| - case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE:
|
| - return "active_and_awaiting_touchstart_response";
|
| - default:
|
| - NOTREACHED();
|
| - return nullptr;
|
| - }
|
| -}
|
| -
|
| -scoped_refptr<base::trace_event::ConvertableToTraceFormat>
|
| -RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
|
| - helper_.CheckOnValidThread();
|
| - incoming_signals_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("idle_period_state",
|
| - SchedulerHelper::IdlePeriodStateToString(
|
| - helper_.SchedulerIdlePeriodState()));
|
| - state->SetBoolean("renderer_hidden_", renderer_hidden_);
|
| - state->SetString("input_stream_state",
|
| - InputStreamStateToString(input_stream_state_));
|
| - state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
|
| - state->SetDouble("last_input_receipt_time_on_compositor_",
|
| - (last_input_receipt_time_on_compositor_ - base::TimeTicks())
|
| - .InMillisecondsF());
|
| - state->SetDouble(
|
| - "last_input_process_time_on_main_",
|
| - (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF());
|
| - state->SetDouble(
|
| - "estimated_next_frame_begin",
|
| - (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF());
|
| -
|
| - return state;
|
| -}
|
| -
|
| -RendererSchedulerImpl::InputStreamState
|
| -RendererSchedulerImpl::ComputeNewInputStreamState(
|
| - InputStreamState current_state,
|
| - blink::WebInputEvent::Type new_input_type,
|
| - blink::WebInputEvent::Type last_input_type) {
|
| - switch (new_input_type) {
|
| - case blink::WebInputEvent::TouchStart:
|
| - return InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE;
|
| -
|
| - case blink::WebInputEvent::TouchMove:
|
| - // Observation of consecutive touchmoves is a strong signal that the page
|
| - // is consuming the touch sequence, in which case touchstart response
|
| - // prioritization is no longer necessary. Otherwise, the initial touchmove
|
| - // should preserve the touchstart response pending state.
|
| - if (current_state ==
|
| - InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE) {
|
| - return last_input_type == blink::WebInputEvent::TouchMove
|
| - ? InputStreamState::ACTIVE
|
| - : InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE;
|
| - }
|
| - break;
|
| -
|
| - case blink::WebInputEvent::GestureTapDown:
|
| - case blink::WebInputEvent::GestureShowPress:
|
| - case blink::WebInputEvent::GestureFlingCancel:
|
| - case blink::WebInputEvent::GestureScrollEnd:
|
| - // With no observable effect, these meta events do not indicate a
|
| - // meaningful touchstart response and should not impact task priority.
|
| - return current_state;
|
| -
|
| - default:
|
| - break;
|
| - }
|
| - return InputStreamState::ACTIVE;
|
| -}
|
| -
|
| -} // namespace content
|
|
|