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

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 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 "cc/output/begin_frame_args.h"
9 #include "content/renderer/scheduler/renderer_task_queue_selector.h"
10 #include "ui/gfx/frame_time.h"
11
12 namespace content {
13
14 RendererSchedulerImpl::RendererSchedulerImpl(
15 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
16 : renderer_task_queue_selector_(new RendererTaskQueueSelector()),
17 task_queue_manager_(
18 new TaskQueueManager(TASK_QUEUE_COUNT,
19 main_task_runner,
20 renderer_task_queue_selector_.get())),
21 control_task_runner_(
22 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)),
23 default_task_runner_(
24 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)),
25 compositor_task_runner_(
26 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
27 current_policy_(NORMAL_PRIORITY_POLICY),
28 policy_may_need_update_(&incoming_signals_lock_),
29 weak_factory_(this) {
30 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
31 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
32 weak_renderer_scheduler_ptr_);
33 end_idle_period_closure_ = base::Bind(&RendererSchedulerImpl::EndIdlePeriod,
34 weak_renderer_scheduler_ptr_);
35 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
36 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
37 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback,
38 weak_renderer_scheduler_ptr_)));
39 renderer_task_queue_selector_->SetQueuePriority(
40 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
41 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
42 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false);
43 }
44
45 RendererSchedulerImpl::~RendererSchedulerImpl() {
46 }
47
48 void RendererSchedulerImpl::Shutdown() {
49 main_thread_checker_.CalledOnValidThread();
50 task_queue_manager_.reset();
51 }
52
53 scoped_refptr<base::SingleThreadTaskRunner>
54 RendererSchedulerImpl::DefaultTaskRunner() {
55 main_thread_checker_.CalledOnValidThread();
56 return default_task_runner_;
57 }
58
59 scoped_refptr<base::SingleThreadTaskRunner>
60 RendererSchedulerImpl::CompositorTaskRunner() {
61 main_thread_checker_.CalledOnValidThread();
62 return compositor_task_runner_;
63 }
64
65 scoped_refptr<SingleThreadIdleTaskRunner>
66 RendererSchedulerImpl::IdleTaskRunner() {
67 main_thread_checker_.CalledOnValidThread();
68 return idle_task_runner_;
69 }
70
71 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
72 main_thread_checker_.CalledOnValidThread();
73 if (!task_queue_manager_)
74 return;
75
76 EndIdlePeriod();
77 estimated_next_frame_begin_ = args.frame_time + args.interval;
78 }
79
80 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
81 main_thread_checker_.CalledOnValidThread();
82 if (!task_queue_manager_)
83 return;
84
85 base::TimeTicks now(Now());
86 if (now < estimated_next_frame_begin_) {
87 StartIdlePeriod();
88 control_task_runner_->PostDelayedTask(FROM_HERE, end_idle_period_closure_,
89 estimated_next_frame_begin_ - now);
90 }
91 }
92
93 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread() {
94 // TODO(rmcilroy): Decide whether only a subset of input events should trigger
95 // compositor priority policy - http://crbug.com/429814.
96 base::AutoLock lock(incoming_signals_lock_);
97 if (last_input_time_.is_null()) {
98 // Update scheduler policy if should start a new compositor policy mode.
99 policy_may_need_update_.SetLocked(true);
100 PostUpdatePolicyOnControlRunner(base::TimeDelta());
101 }
102 last_input_time_ = Now();
103 }
104
105 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
106 main_thread_checker_.CalledOnValidThread();
107 if (!task_queue_manager_)
108 return false;
109
110 MaybeUpdatePolicy();
no sievers 2014/11/05 21:18:57 nit: Put a comment here explaining that we do want
rmcilroy 2014/11/05 22:40:34 Done.
111 return SchedulerPolicy() == COMPOSITOR_PRIORITY_POLICY &&
112 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
113 }
114
115 void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback(
116 base::TimeTicks* deadline_out) const {
117 main_thread_checker_.CalledOnValidThread();
118 *deadline_out = estimated_next_frame_begin_;
119 }
120
121 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const {
122 main_thread_checker_.CalledOnValidThread();
123 return current_policy_;
124 }
125
126 void RendererSchedulerImpl::MaybeUpdatePolicy() {
127 main_thread_checker_.CalledOnValidThread();
128 if (policy_may_need_update_.IsSet()) {
129 UpdatePolicy();
130 }
131 }
132
133 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner(
134 base::TimeDelta delay) {
135 control_task_runner_->PostDelayedTask(FROM_HERE, update_policy_closure_,
136 delay);
137 }
138
139 void RendererSchedulerImpl::UpdatePolicy() {
140 main_thread_checker_.CalledOnValidThread();
141 if (!task_queue_manager_)
142 return;
143
144 base::AutoLock lock(incoming_signals_lock_);
145 policy_may_need_update_.SetLocked(false);
146
147 Policy new_policy = NORMAL_PRIORITY_POLICY;
148 if (!last_input_time_.is_null()) {
149 base::TimeDelta compositor_priority_duration =
150 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
151 base::TimeTicks compositor_priority_end(last_input_time_ +
152 compositor_priority_duration);
153 base::TimeTicks now(Now());
154 if (compositor_priority_end > now) {
155 PostUpdatePolicyOnControlRunner(compositor_priority_end - now);
156 new_policy = COMPOSITOR_PRIORITY_POLICY;
157 } else {
158 // Null out last_input_time_ to ensure
159 // DidReceiveInputEventOnCompositorThread will post an
160 // UpdatePolicy task when it's next called.
161 last_input_time_ = base::TimeTicks();
162 }
163 }
164
165 if (new_policy == current_policy_)
166 return;
167
168 switch (new_policy) {
169 case COMPOSITOR_PRIORITY_POLICY:
170 renderer_task_queue_selector_->SetQueuePriority(
171 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
172 break;
173 case NORMAL_PRIORITY_POLICY:
174 renderer_task_queue_selector_->SetQueuePriority(
175 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
176 break;
177 }
178 current_policy_ = new_policy;
179 }
180
181 void RendererSchedulerImpl::StartIdlePeriod() {
182 main_thread_checker_.CalledOnValidThread();
183 renderer_task_queue_selector_->EnableQueue(
184 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
185 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
186 }
187
188 void RendererSchedulerImpl::EndIdlePeriod() {
189 main_thread_checker_.CalledOnValidThread();
190 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
191 }
192
193 base::TimeTicks RendererSchedulerImpl::Now() const {
194 return gfx::FrameTime::Now();
195 }
196
197 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
198 base::Lock* write_lock_)
199 : flag_(false), write_lock_(write_lock_) {
200 }
201
202 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() {
203 }
204
205 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetLocked(bool value) {
206 write_lock_->AssertAcquired();
207 base::subtle::Release_Store(&flag_, value);
208 }
209
210 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
211 thread_checker_.CalledOnValidThread();
212 return base::subtle::Acquire_Load(&flag_) != 0;
213 }
214 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/scheduler/renderer_scheduler_impl.h ('k') | content/renderer/scheduler/renderer_scheduler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698