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

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: Fix nits 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_task_queue_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_task_queue_selector_(new RendererTaskQueueSelector()),
22 task_queue_manager_(
23 new TaskQueueManager(TASK_QUEUE_COUNT,
24 main_task_runner,
25 renderer_task_queue_selector_.get())),
26 control_task_runner_(
27 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)),
28 default_task_runner_(
29 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)),
30 compositor_task_runner_(
31 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
32 current_policy_(NORMAL_PRIORITY_POLICY),
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(IDLE_TASK_QUEUE),
38 weak_factory_.GetWeakPtr()));
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 task_queue_manager_.reset();
50 }
51
52 scoped_refptr<base::SingleThreadTaskRunner>
53 RendererSchedulerImpl::DefaultTaskRunner() {
no sievers 2014/10/30 23:40:51 What about these task runner getter methods being
alex clarke (OOO till 29th) 2014/11/03 17:39:34 If a task gets posted during shut down, then it wi
rmcilroy 2014/11/03 19:02:52 This should be fine - the task_runners are ref_cou
no sievers 2014/11/03 22:19:01 But these getters should call main_thread_checker_
rmcilroy 2014/11/04 02:22:19 Yes, these getters should call main_thread_checker
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_)
no sievers 2014/10/30 23:40:51 Do we really expect this after shutdown? Should it
rmcilroy 2014/11/03 19:02:52 Unfortunately we can still get called by the compo
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_)
no sievers 2014/10/30 23:40:51 This is accessing task_queue_manager_ without a mu
rmcilroy 2014/11/03 19:02:52 Very good point. I've removed the check entirely
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() == COMPOSITOR_PRIORITY_POLICY &&
104 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE);
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();
no sievers 2014/10/30 23:40:51 Why do we need to do this here? We know that if it
alex clarke (OOO till 29th) 2014/11/03 17:39:33 The motivation for this is to let ShouldYieldForHi
rmcilroy 2014/11/03 19:02:52 We need this due to the ShouldYieldForHighPriority
no sievers 2014/11/03 22:19:01 Shouldn't it also yield then for any control task
rmcilroy 2014/11/04 02:22:19 As discussed offline, this doesn't quite give us w
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 control_task_runner_->PostDelayedTask(FROM_HERE, closure, delay);
125 }
126
127 void RendererSchedulerImpl::UpdatePolicy() {
128 main_thread_checker_.CalledOnValidThread();
129 if (!task_queue_manager_)
130 return;
131
132 base::AutoLock lock(incoming_signals_lock_);
133 base::subtle::Release_Store(&policy_may_need_update_, 0);
134
135 Policy new_policy = NORMAL_PRIORITY_POLICY;
136 if (!last_input_time_.is_null()) {
137 base::TimeDelta compositor_priority_duration =
no sievers 2014/10/30 23:40:51 nit: indent
rmcilroy 2014/11/03 19:02:52 I'm not sure what's wrongly indented here?
138 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
139 base::TimeDelta remaining_compositor_priority_duration =
140 last_input_time_ + compositor_priority_duration - Now();
141 if (remaining_compositor_priority_duration > base::TimeDelta()) {
no sievers 2014/10/30 23:40:51 nit: can you write instead: base::TimeTicks prior
rmcilroy 2014/11/03 19:02:52 Done.
142 PostUpdatePolicyOnControlRunner(remaining_compositor_priority_duration);
143 new_policy = COMPOSITOR_PRIORITY_POLICY;
144 } else {
145 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an
146 // UpdatePolicy task when it's next called.
147 last_input_time_ = base::TimeTicks();
148 }
149 }
150
151 if (new_policy == current_policy_) {
152 return;
153 }
154
155 switch (new_policy) {
156 case COMPOSITOR_PRIORITY_POLICY:
157 renderer_task_queue_selector_->SetQueuePriority(
158 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
159 break;
160 case NORMAL_PRIORITY_POLICY:
161 renderer_task_queue_selector_->SetQueuePriority(
162 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
163 break;
164 }
165 current_policy_ = new_policy;
166 }
167
168 void RendererSchedulerImpl::StartIdlePeriod() {
169 renderer_task_queue_selector_->EnableQueue(
170 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
171 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
172 }
173
174 void RendererSchedulerImpl::EndIdlePeriod() {
175 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
176 }
177
178 base::TimeTicks RendererSchedulerImpl::Now() const {
179 return gfx::FrameTime::Now();
180 }
181
182 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698