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

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 Daniel and Jared's comments and move renderer_scheduler ownership to render_thread_impl 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(
89 FROM_HERE, end_idle_period_closure_, estimated_next_frame_begin_ - now);
90 }
91 }
92
93 void RendererSchedulerImpl::DidReceiveInputEvent() {
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 return SchedulerPolicy() == COMPOSITOR_PRIORITY_POLICY &&
111 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
112 }
113
114 void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback(
115 base::TimeTicks* deadline_out) const {
116 main_thread_checker_.CalledOnValidThread();
117 *deadline_out = estimated_next_frame_begin_;
118 }
119
120 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() {
121 main_thread_checker_.CalledOnValidThread();
no sievers 2014/11/04 20:41:41 How about inlining this code into ShouldYieldForHi
rmcilroy 2014/11/05 00:34:00 OK I guess this would work, I moved it to MaybeUpd
122 if (policy_may_need_update_.IsSet()) {
123 UpdatePolicy();
124 }
125 return current_policy_;
126 }
127
128 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner(
129 base::TimeDelta delay) {
130 control_task_runner_->PostDelayedTask(
131 FROM_HERE, update_policy_closure_, delay);
132 }
133
134 void RendererSchedulerImpl::UpdatePolicy() {
135 main_thread_checker_.CalledOnValidThread();
136 if (!task_queue_manager_)
137 return;
138
139 base::AutoLock lock(incoming_signals_lock_);
140 policy_may_need_update_.SetLocked(false);
141
142 Policy new_policy = NORMAL_PRIORITY_POLICY;
143 if (!last_input_time_.is_null()) {
144 base::TimeDelta compositor_priority_duration =
145 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
146 base::TimeTicks compositor_priority_end(last_input_time_ +
147 compositor_priority_duration);
148 base::TimeTicks now(Now());
149 if (compositor_priority_end > now) {
150 PostUpdatePolicyOnControlRunner(compositor_priority_end - now);
151 new_policy = COMPOSITOR_PRIORITY_POLICY;
152 } else {
153 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an
154 // UpdatePolicy task when it's next called.
155 last_input_time_ = base::TimeTicks();
156 }
157 }
158
159 if (new_policy == current_policy_)
160 return;
161
162 switch (new_policy) {
163 case COMPOSITOR_PRIORITY_POLICY:
164 renderer_task_queue_selector_->SetQueuePriority(
165 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
166 break;
167 case NORMAL_PRIORITY_POLICY:
168 renderer_task_queue_selector_->SetQueuePriority(
169 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
170 break;
171 }
172 current_policy_ = new_policy;
173 }
174
175 void RendererSchedulerImpl::StartIdlePeriod() {
176 renderer_task_queue_selector_->EnableQueue(
Sami 2014/11/04 17:46:35 nit: add a main thread check here.
rmcilroy 2014/11/05 00:34:00 Done.
177 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
178 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
179 }
180
181 void RendererSchedulerImpl::EndIdlePeriod() {
Sami 2014/11/04 17:46:35 nit: add a main thread check here.
rmcilroy 2014/11/05 00:34:00 Done.
182 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
183 }
184
185 base::TimeTicks RendererSchedulerImpl::Now() const {
186 return gfx::FrameTime::Now();
187 }
188
189 PolicyNeedsUpdateFlag::PolicyNeedsUpdateFlag(base::Lock* write_lock_)
190 : flag_(false), write_lock_(write_lock_) {
191 }
192
193 PolicyNeedsUpdateFlag::~PolicyNeedsUpdateFlag() {
194 }
195
196 void PolicyNeedsUpdateFlag::SetLocked(bool value) {
197 write_lock_->AssertAcquired();
198 base::subtle::Release_Store(&flag_, value);
199 }
200
201 bool PolicyNeedsUpdateFlag::IsSet() const {
202 thread_checker_.CalledOnValidThread();
203 return base::subtle::Acquire_Load(&flag_) != 0;
204 }
205 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698