OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" | 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | |
9 #include "base/debug/trace_event_argument.h" | |
8 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
9 #include "cc/output/begin_frame_args.h" | 11 #include "cc/output/begin_frame_args.h" |
10 #include "content/renderer/scheduler/renderer_task_queue_selector.h" | 12 #include "content/renderer/scheduler/renderer_task_queue_selector.h" |
11 #include "ui/gfx/frame_time.h" | 13 #include "ui/gfx/frame_time.h" |
12 | 14 |
13 namespace content { | 15 namespace content { |
14 | 16 |
15 RendererSchedulerImpl::RendererSchedulerImpl() | 17 RendererSchedulerImpl::RendererSchedulerImpl() |
16 : RendererSchedulerImpl(base::MessageLoopProxy::current()) { | 18 : RendererSchedulerImpl(base::MessageLoopProxy::current()) { |
17 } | 19 } |
(...skipping 15 matching lines...) Expand all Loading... | |
33 policy_may_need_update_(0), | 35 policy_may_need_update_(0), |
34 weak_factory_(this) { | 36 weak_factory_(this) { |
35 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); | 37 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); |
36 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( | 38 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( |
37 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), | 39 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), |
38 weak_factory_.GetWeakPtr())); | 40 weak_factory_.GetWeakPtr())); |
39 renderer_task_queue_selector_->SetQueuePriority( | 41 renderer_task_queue_selector_->SetQueuePriority( |
40 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); | 42 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); |
41 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); | 43 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); |
42 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false); | 44 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false); |
45 | |
46 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) { | |
47 task_queue_manager_->SetQueueName( | |
48 i, TaskQueueIdToString(static_cast<QueueId>(i))); | |
49 } | |
50 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | |
51 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
52 "RendererScheduler", | |
53 this); | |
43 } | 54 } |
44 | 55 |
45 RendererSchedulerImpl::~RendererSchedulerImpl() { | 56 RendererSchedulerImpl::~RendererSchedulerImpl() { |
46 } | 57 } |
47 | 58 |
48 void RendererSchedulerImpl::Shutdown() { | 59 void RendererSchedulerImpl::Shutdown() { |
49 task_queue_manager_.reset(); | 60 task_queue_manager_.reset(); |
50 } | 61 } |
51 | 62 |
52 scoped_refptr<base::SingleThreadTaskRunner> | 63 scoped_refptr<base::SingleThreadTaskRunner> |
53 RendererSchedulerImpl::DefaultTaskRunner() { | 64 RendererSchedulerImpl::DefaultTaskRunner() { |
54 return default_task_runner_; | 65 return default_task_runner_; |
55 } | 66 } |
56 | 67 |
57 scoped_refptr<base::SingleThreadTaskRunner> | 68 scoped_refptr<base::SingleThreadTaskRunner> |
58 RendererSchedulerImpl::CompositorTaskRunner() { | 69 RendererSchedulerImpl::CompositorTaskRunner() { |
59 return compositor_task_runner_; | 70 return compositor_task_runner_; |
60 } | 71 } |
61 | 72 |
62 scoped_refptr<SingleThreadIdleTaskRunner> | 73 scoped_refptr<SingleThreadIdleTaskRunner> |
63 RendererSchedulerImpl::IdleTaskRunner() { | 74 RendererSchedulerImpl::IdleTaskRunner() { |
64 return idle_task_runner_; | 75 return idle_task_runner_; |
65 } | 76 } |
66 | 77 |
67 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { | 78 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { |
79 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
80 "RendererSchedulerImpl::WillBeginFrame"); | |
rmcilroy
2014/11/07 18:21:57
Would it be worth passing the args values (frame_t
Sami
2014/11/10 14:35:01
Good idea. Looks like |args| already knows how to
| |
68 main_thread_checker_.CalledOnValidThread(); | 81 main_thread_checker_.CalledOnValidThread(); |
69 if (!task_queue_manager_) | 82 if (!task_queue_manager_) |
70 return; | 83 return; |
71 | 84 |
72 EndIdlePeriod(); | 85 EndIdlePeriod(); |
73 estimated_next_frame_begin_ = args.frame_time + args.interval; | 86 estimated_next_frame_begin_ = args.frame_time + args.interval; |
74 } | 87 } |
75 | 88 |
76 void RendererSchedulerImpl::DidCommitFrameToCompositor() { | 89 void RendererSchedulerImpl::DidCommitFrameToCompositor() { |
90 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
91 "RendererSchedulerImpl::DidCommitFrameToCompositor"); | |
77 main_thread_checker_.CalledOnValidThread(); | 92 main_thread_checker_.CalledOnValidThread(); |
78 if (!task_queue_manager_) | 93 if (!task_queue_manager_) |
79 return; | 94 return; |
80 | 95 |
81 if (Now() < estimated_next_frame_begin_) { | 96 if (Now() < estimated_next_frame_begin_) { |
82 StartIdlePeriod(); | 97 StartIdlePeriod(); |
83 } | 98 } |
84 } | 99 } |
85 | 100 |
86 void RendererSchedulerImpl::DidReceiveInputEvent() { | 101 void RendererSchedulerImpl::DidReceiveInputEvent() { |
102 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
103 "RendererSchedulerImpl::DidReceiveInputEvent"); | |
87 if (!task_queue_manager_) | 104 if (!task_queue_manager_) |
88 return; | 105 return; |
89 base::AutoLock lock(incoming_signals_lock_); | 106 base::AutoLock lock(incoming_signals_lock_); |
90 if (last_input_time_.is_null()) { | 107 if (last_input_time_.is_null()) { |
91 // Update scheduler policy if should start a new compositor policy mode. | 108 // Update scheduler policy if should start a new compositor policy mode. |
92 base::subtle::Release_Store(&policy_may_need_update_, 1); | 109 base::subtle::Release_Store(&policy_may_need_update_, 1); |
93 PostUpdatePolicyOnControlRunner(base::TimeDelta()); | 110 PostUpdatePolicyOnControlRunner(base::TimeDelta()); |
94 } | 111 } |
95 last_input_time_ = Now(); | 112 last_input_time_ = Now(); |
96 } | 113 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 } | 145 } |
129 } | 146 } |
130 | 147 |
131 void RendererSchedulerImpl::UpdatePolicy() { | 148 void RendererSchedulerImpl::UpdatePolicy() { |
132 main_thread_checker_.CalledOnValidThread(); | 149 main_thread_checker_.CalledOnValidThread(); |
133 if (!task_queue_manager_) | 150 if (!task_queue_manager_) |
134 return; | 151 return; |
135 | 152 |
136 base::AutoLock lock(incoming_signals_lock_); | 153 base::AutoLock lock(incoming_signals_lock_); |
137 base::subtle::Release_Store(&policy_may_need_update_, 0); | 154 base::subtle::Release_Store(&policy_may_need_update_, 0); |
155 base::TimeTicks now; | |
138 | 156 |
139 Policy new_policy = NORMAL_PRIORITY_POLICY; | 157 Policy new_policy = NORMAL_PRIORITY_POLICY; |
140 if (!last_input_time_.is_null()) { | 158 if (!last_input_time_.is_null()) { |
159 now = Now(); | |
141 base::TimeDelta compositor_priority_duration = | 160 base::TimeDelta compositor_priority_duration = |
142 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis); | 161 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis); |
143 base::TimeDelta remaining_compositor_priority_duration = | 162 base::TimeDelta remaining_compositor_priority_duration = |
144 last_input_time_ + compositor_priority_duration - Now(); | 163 last_input_time_ + compositor_priority_duration - now; |
145 if (remaining_compositor_priority_duration > base::TimeDelta()) { | 164 if (remaining_compositor_priority_duration > base::TimeDelta()) { |
146 PostUpdatePolicyOnControlRunner(remaining_compositor_priority_duration); | 165 PostUpdatePolicyOnControlRunner(remaining_compositor_priority_duration); |
147 new_policy = COMPOSITOR_PRIORITY_POLICY; | 166 new_policy = COMPOSITOR_PRIORITY_POLICY; |
148 } else { | 167 } else { |
149 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an | 168 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an |
150 // UpdatePolicy task when it's next called. | 169 // UpdatePolicy task when it's next called. |
151 last_input_time_ = base::TimeTicks(); | 170 last_input_time_ = base::TimeTicks(); |
152 } | 171 } |
153 } | 172 } |
154 | 173 |
155 if (new_policy == current_policy_) { | 174 if (new_policy == current_policy_) { |
156 return; | 175 return; |
157 } | 176 } |
158 | 177 |
159 switch (new_policy) { | 178 switch (new_policy) { |
160 case COMPOSITOR_PRIORITY_POLICY: | 179 case COMPOSITOR_PRIORITY_POLICY: |
161 renderer_task_queue_selector_->SetQueuePriority( | 180 renderer_task_queue_selector_->SetQueuePriority( |
162 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); | 181 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); |
163 break; | 182 break; |
164 case NORMAL_PRIORITY_POLICY: | 183 case NORMAL_PRIORITY_POLICY: |
165 renderer_task_queue_selector_->SetQueuePriority( | 184 renderer_task_queue_selector_->SetQueuePriority( |
166 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); | 185 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); |
167 break; | 186 break; |
168 } | 187 } |
169 current_policy_ = new_policy; | 188 current_policy_ = new_policy; |
189 | |
190 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | |
191 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
192 "RendererScheduler", | |
193 this, | |
194 AsValueLocked(now)); | |
195 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
196 "RendererScheduler.policy", | |
197 current_policy_); | |
170 } | 198 } |
171 | 199 |
172 void RendererSchedulerImpl::StartIdlePeriod() { | 200 void RendererSchedulerImpl::StartIdlePeriod() { |
201 TRACE_EVENT_ASYNC_BEGIN0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
202 "RendererSchedulerIdlePeriod", | |
203 this); | |
173 renderer_task_queue_selector_->EnableQueue( | 204 renderer_task_queue_selector_->EnableQueue( |
174 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); | 205 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); |
175 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); | 206 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); |
176 } | 207 } |
177 | 208 |
178 void RendererSchedulerImpl::EndIdlePeriod() { | 209 void RendererSchedulerImpl::EndIdlePeriod() { |
210 TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | |
211 "RendererSchedulerIdlePeriod", | |
212 this); | |
179 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); | 213 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); |
180 } | 214 } |
181 | 215 |
182 base::TimeTicks RendererSchedulerImpl::Now() const { | 216 base::TimeTicks RendererSchedulerImpl::Now() const { |
183 return gfx::FrameTime::Now(); | 217 return gfx::FrameTime::Now(); |
184 } | 218 } |
185 | 219 |
220 // static | |
221 const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) { | |
222 switch (queue_id) { | |
223 case DEFAULT_TASK_QUEUE: | |
224 return "default_tq"; | |
225 case COMPOSITOR_TASK_QUEUE: | |
226 return "compositor_tq"; | |
227 case IDLE_TASK_QUEUE: | |
228 return "idle_tq"; | |
229 case CONTROL_TASK_QUEUE: | |
230 return "control_tq"; | |
231 default: | |
232 NOTREACHED(); | |
233 return nullptr; | |
234 } | |
235 } | |
236 | |
237 // static | |
238 const char* RendererSchedulerImpl::PolicyToString(Policy policy) { | |
239 switch (policy) { | |
240 case NORMAL_PRIORITY_POLICY: | |
241 return "normal"; | |
242 case COMPOSITOR_PRIORITY_POLICY: | |
243 return "compositor"; | |
244 default: | |
245 NOTREACHED(); | |
246 return nullptr; | |
247 } | |
248 } | |
249 | |
250 scoped_refptr<base::debug::ConvertableToTraceFormat> | |
251 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { | |
252 main_thread_checker_.CalledOnValidThread(); | |
253 incoming_signals_lock_.AssertAcquired(); | |
254 | |
255 if (optional_now.is_null()) | |
256 optional_now = Now(); | |
257 scoped_refptr<base::debug::TracedValue> state = | |
258 new base::debug::TracedValue(); | |
259 | |
260 state->SetString("current_policy", PolicyToString(current_policy_)); | |
261 state->SetBoolean("has_task_queue_manager", task_queue_manager_.get()); | |
262 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | |
263 state->SetDouble("last_input_time", | |
264 (last_input_time_ - base::TimeTicks()).InMillisecondsF()); | |
265 state->SetDouble( | |
266 "estimated_next_frame_begin", | |
267 (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF()); | |
268 | |
269 return state; | |
270 } | |
271 | |
186 } // namespace content | 272 } // namespace content |
OLD | NEW |