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

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

Issue 664963002: content: Add RendererScheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Alex's comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "cc/output/begin_frame_args.h"
10 #include "content/renderer/scheduler/renderer_scheduler_selector.h"
11 #include "ui/gfx/frame_time.h"
12
13 namespace content {
14
15 RendererSchedulerImpl::RendererSchedulerImpl()
16 : RendererSchedulerImpl(base::MessageLoopProxy::current()) {
17 }
18
19 RendererSchedulerImpl::RendererSchedulerImpl(
20 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
21 : renderer_scheduler_selector_(new RendererSchedulerSelector()),
22 task_queue_manager_(
23 new TaskQueueManager(kTaskQueueCount,
24 main_task_runner,
25 renderer_scheduler_selector_.get())),
26 control_task_runner_(
27 task_queue_manager_->TaskRunnerForQueue(kControlTaskQueue)),
28 default_task_runner_(
29 task_queue_manager_->TaskRunnerForQueue(kDefaultTaskQueue)),
30 compositor_task_runner_(
31 task_queue_manager_->TaskRunnerForQueue(kCompositorTaskQueue)),
32 current_policy_(kNormalPriorityPolicy),
33 policy_may_need_update_(0),
34 weak_factory_(this) {
35 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
36 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
37 task_queue_manager_->TaskRunnerForQueue(kIdleTaskQueue),
38 weak_factory_.GetWeakPtr()));
39 renderer_scheduler_selector_->SetQueuePriority(
40 kControlTaskQueue, RendererSchedulerSelector::kControlPriority);
41 renderer_scheduler_selector_->DisableQueue(kIdleTaskQueue);
42 task_queue_manager_->SetAutoPump(kIdleTaskQueue, false);
43 }
44
45 RendererSchedulerImpl::~RendererSchedulerImpl() {
46 }
47
48 void RendererSchedulerImpl::Shutdown() {
49 task_queue_manager_.reset();
50 }
51
52 scoped_refptr<base::SingleThreadTaskRunner>
53 RendererSchedulerImpl::DefaultTaskRunner() {
54 return default_task_runner_;
55 }
56
57 scoped_refptr<base::SingleThreadTaskRunner>
58 RendererSchedulerImpl::CompositorTaskRunner() {
59 return compositor_task_runner_;
60 }
61
62 scoped_refptr<SingleThreadIdleTaskRunner>
63 RendererSchedulerImpl::IdleTaskRunner() {
64 return idle_task_runner_;
65 }
66
67 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
68 main_thread_checker_.CalledOnValidThread();
69 if (!task_queue_manager_)
70 return;
71
72 EndIdlePeriod();
73 estimated_next_frame_begin_ = args.frame_time + args.interval;
74 }
75
76 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
77 main_thread_checker_.CalledOnValidThread();
78 if (!task_queue_manager_)
79 return;
80
81 if (Now() < estimated_next_frame_begin_) {
82 StartIdlePeriod();
83 }
84 }
85
86 void RendererSchedulerImpl::DidReceiveInputEvent() {
87 if (!task_queue_manager_)
88 return;
89 base::AutoLock lock(incoming_signals_lock_);
90 if (last_input_time_.is_null()) {
91 // Update scheduler policy if should start a new compositor policy mode.
92 base::subtle::Release_Store(&policy_may_need_update_, 1);
93 PostUpdatePolicyOnControlRunner(base::TimeDelta());
94 }
95 last_input_time_ = Now();
96 }
97
98 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
99 main_thread_checker_.CalledOnValidThread();
100 if (!task_queue_manager_)
101 return false;
102
103 return SchedulerPolicy() == kCompositorPriorityPolicy &&
104 !task_queue_manager_->IsQueueEmpty(kCompositorTaskQueue);
105 }
106
107 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadline() const {
108 main_thread_checker_.CalledOnValidThread();
109 return estimated_next_frame_begin_;
110 }
111
112 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() {
113 main_thread_checker_.CalledOnValidThread();
114 if (base::subtle::Acquire_Load(&policy_may_need_update_)) {
115 UpdatePolicy();
116 }
117 return current_policy_;
118 }
119
120 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner(
121 base::TimeDelta delay) {
122 base::Closure closure = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
123 weak_renderer_scheduler_ptr_);
124 if (delay > base::TimeDelta()) {
125 control_task_runner_->PostDelayedTask(FROM_HERE, closure, delay);
126 } else {
127 control_task_runner_->PostTask(FROM_HERE, closure);
128 }
129 }
130
131 void RendererSchedulerImpl::UpdatePolicy() {
132 main_thread_checker_.CalledOnValidThread();
133 if (!task_queue_manager_)
134 return;
135
136 base::AutoLock lock(incoming_signals_lock_);
137 base::subtle::Release_Store(&policy_may_need_update_, 0);
138
139 Policy new_policy = kNormalPriorityPolicy;
140 if (!last_input_time_.is_null()) {
141 base::TimeDelta compositor_priority_duration =
142 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
143 base::TimeDelta remaining_compositor_priority_duration =
144 last_input_time_ + compositor_priority_duration - Now();
145 if (remaining_compositor_priority_duration > base::TimeDelta()) {
146 PostUpdatePolicyOnControlRunner(remaining_compositor_priority_duration);
147 new_policy = kCompositorPriorityPolicy;
148 } else {
149 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an
150 // UpdatePolicy task when it's next called.
151 last_input_time_ = base::TimeTicks();
152 }
153 }
154
155 if (new_policy == current_policy_) {
156 return;
157 }
158
159 switch (new_policy) {
160 case kCompositorPriorityPolicy:
161 renderer_scheduler_selector_->SetQueuePriority(
162 kCompositorTaskQueue, RendererSchedulerSelector::kHighPriority);
163 break;
164 case kNormalPriorityPolicy:
165 renderer_scheduler_selector_->SetQueuePriority(
166 kCompositorTaskQueue, RendererSchedulerSelector::kNormalPriority);
167 break;
168 }
169 current_policy_ = new_policy;
170 }
171
172 void RendererSchedulerImpl::StartIdlePeriod() {
173 renderer_scheduler_selector_->EnableQueue(
174 kIdleTaskQueue, RendererSchedulerSelector::kBestEffortPriority);
175 task_queue_manager_->PumpQueue(kIdleTaskQueue);
176 }
177
178 void RendererSchedulerImpl::EndIdlePeriod() {
179 renderer_scheduler_selector_->DisableQueue(kIdleTaskQueue);
180 }
181
182 base::TimeTicks RendererSchedulerImpl::Now() const {
183 return gfx::FrameTime::Now();
184 }
185
186 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698