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

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: Add TODO and CONTENT_EXPORT for tests. 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 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
32 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
33 weak_factory_.GetWeakPtr()));
34 renderer_task_queue_selector_->SetQueuePriority(
35 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
36 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
37 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false);
38 }
39
40 RendererSchedulerImpl::~RendererSchedulerImpl() {
41 }
42
43 void RendererSchedulerImpl::Shutdown() {
44 task_queue_manager_.reset();
45 }
46
47 scoped_refptr<base::SingleThreadTaskRunner>
48 RendererSchedulerImpl::DefaultTaskRunner() {
49 return default_task_runner_;
50 }
51
52 scoped_refptr<base::SingleThreadTaskRunner>
53 RendererSchedulerImpl::CompositorTaskRunner() {
54 return compositor_task_runner_;
55 }
56
57 scoped_refptr<SingleThreadIdleTaskRunner>
58 RendererSchedulerImpl::IdleTaskRunner() {
59 return idle_task_runner_;
60 }
61
62 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
63 main_thread_checker_.CalledOnValidThread();
64 if (!task_queue_manager_)
65 return;
66
67 EndIdlePeriod();
68 estimated_next_frame_begin_ = args.frame_time + args.interval;
69 }
70
71 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
72 main_thread_checker_.CalledOnValidThread();
73 if (!task_queue_manager_)
74 return;
75
76 base::TimeTicks now(Now());
77 if (now < estimated_next_frame_begin_) {
78 StartIdlePeriod();
79 control_task_runner_->PostDelayedTask(
80 FROM_HERE,
81 base::Bind(&RendererSchedulerImpl::EndIdlePeriod,
82 weak_renderer_scheduler_ptr_),
jdduke (slow) 2014/11/03 21:33:48 See below (wondering if caching the closure provid
rmcilroy 2014/11/04 02:22:20 Done.
83 estimated_next_frame_begin_ - now);
84 }
85 }
86
87 void RendererSchedulerImpl::DidReceiveInputEvent() {
88 // TODO(rmcilroy): Decide whether only a subset of input events should trigger
89 // compositor priority policy - http://crbug.com/429814.
90 base::AutoLock lock(incoming_signals_lock_);
91 if (last_input_time_.is_null()) {
92 // Update scheduler policy if should start a new compositor policy mode.
93 policy_may_need_update_.SetLocked(true);
94 PostUpdatePolicyOnControlRunner(base::TimeDelta());
95 }
96 last_input_time_ = Now();
97 }
98
99 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
100 main_thread_checker_.CalledOnValidThread();
101 if (!task_queue_manager_)
102 return false;
103
104 return SchedulerPolicy() == COMPOSITOR_PRIORITY_POLICY &&
105 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
106 }
107
108 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadline() const {
109 main_thread_checker_.CalledOnValidThread();
110 return estimated_next_frame_begin_;
111 }
112
113 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() {
114 main_thread_checker_.CalledOnValidThread();
115 if (policy_may_need_update_.IsSet()) {
116 UpdatePolicy();
117 }
118 return current_policy_;
119 }
120
121 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner(
122 base::TimeDelta delay) {
123 base::Closure closure = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
jdduke (slow) 2014/11/03 21:33:48 It looks like |weak_renderer_scheduler_ptr_| never
rmcilroy 2014/11/04 02:22:20 Yes, it looks like caching the closure would avoid
124 weak_renderer_scheduler_ptr_);
125 control_task_runner_->PostDelayedTask(FROM_HERE, closure, delay);
126 }
127
128 void RendererSchedulerImpl::UpdatePolicy() {
129 main_thread_checker_.CalledOnValidThread();
130 if (!task_queue_manager_)
131 return;
132
133 base::AutoLock lock(incoming_signals_lock_);
134 policy_may_need_update_.SetLocked(false);
135
136 Policy new_policy = NORMAL_PRIORITY_POLICY;
137 if (!last_input_time_.is_null()) {
138 base::TimeDelta compositor_priority_duration =
139 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
140 base::TimeTicks compositor_priority_end(last_input_time_ +
141 compositor_priority_duration);
142 base::TimeTicks now(Now());
143 if (compositor_priority_end > now) {
144 PostUpdatePolicyOnControlRunner(compositor_priority_end - now);
145 new_policy = COMPOSITOR_PRIORITY_POLICY;
146 } else {
147 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an
148 // UpdatePolicy task when it's next called.
149 last_input_time_ = base::TimeTicks();
150 }
151 }
152
153 if (new_policy == current_policy_) {
jdduke (slow) 2014/11/03 21:33:48 Nit: No braces necessary.
rmcilroy 2014/11/04 02:22:20 Done.
154 return;
155 }
156
157 switch (new_policy) {
158 case COMPOSITOR_PRIORITY_POLICY:
159 renderer_task_queue_selector_->SetQueuePriority(
160 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
161 break;
162 case NORMAL_PRIORITY_POLICY:
163 renderer_task_queue_selector_->SetQueuePriority(
164 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
165 break;
166 }
167 current_policy_ = new_policy;
168 }
169
170 void RendererSchedulerImpl::StartIdlePeriod() {
171 renderer_task_queue_selector_->EnableQueue(
172 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
173 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
174 }
175
176 void RendererSchedulerImpl::EndIdlePeriod() {
177 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
178 }
179
180 base::TimeTicks RendererSchedulerImpl::Now() const {
181 return gfx::FrameTime::Now();
182 }
183
184 PolicyNeedsUpdateFlag::PolicyNeedsUpdateFlag(base::Lock* write_lock_)
185 : flag_(false), write_lock_(write_lock_) {
186 }
187
188 PolicyNeedsUpdateFlag::~PolicyNeedsUpdateFlag() {
189 }
190
191 void PolicyNeedsUpdateFlag::SetLocked(bool value) {
192 write_lock_->AssertAcquired();
193 base::subtle::Release_Store(&flag_, value);
194 }
195
196 bool PolicyNeedsUpdateFlag::IsSet() const {
197 thread_checker_.CalledOnValidThread();
198 return base::subtle::Acquire_Load(&flag_);
199 }
200 } // 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