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

Side by Side Diff: content/renderer/scheduler/renderer_scheduler_impl.cc

Issue 681793003: scheduler: Add support for tracing scheduler state (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test. 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
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"
10 #include "base/message_loop/message_loop_proxy.h"
8 #include "cc/output/begin_frame_args.h" 11 #include "cc/output/begin_frame_args.h"
9 #include "content/renderer/scheduler/renderer_task_queue_selector.h" 12 #include "content/renderer/scheduler/renderer_task_queue_selector.h"
10 #include "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
11 14
12 namespace content { 15 namespace content {
13 16
14 RendererSchedulerImpl::RendererSchedulerImpl( 17 RendererSchedulerImpl::RendererSchedulerImpl(
15 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) 18 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
16 : renderer_task_queue_selector_(new RendererTaskQueueSelector()), 19 : renderer_task_queue_selector_(new RendererTaskQueueSelector()),
17 task_queue_manager_( 20 task_queue_manager_(
(...skipping 15 matching lines...) Expand all
33 end_idle_period_closure_ = base::Bind(&RendererSchedulerImpl::EndIdlePeriod, 36 end_idle_period_closure_ = base::Bind(&RendererSchedulerImpl::EndIdlePeriod,
34 weak_renderer_scheduler_ptr_); 37 weak_renderer_scheduler_ptr_);
35 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( 38 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
36 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), 39 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
37 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, 40 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback,
38 weak_renderer_scheduler_ptr_))); 41 weak_renderer_scheduler_ptr_)));
39 renderer_task_queue_selector_->SetQueuePriority( 42 renderer_task_queue_selector_->SetQueuePriority(
40 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); 43 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
41 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); 44 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
42 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false); 45 task_queue_manager_->SetAutoPump(IDLE_TASK_QUEUE, false);
46
47 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) {
48 task_queue_manager_->SetQueueName(
49 i, TaskQueueIdToString(static_cast<QueueId>(i)));
50 }
51 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
52 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
53 this);
43 } 54 }
44 55
45 RendererSchedulerImpl::~RendererSchedulerImpl() { 56 RendererSchedulerImpl::~RendererSchedulerImpl() {
57 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
58 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
59 this);
46 } 60 }
47 61
48 void RendererSchedulerImpl::Shutdown() { 62 void RendererSchedulerImpl::Shutdown() {
49 main_thread_checker_.CalledOnValidThread(); 63 main_thread_checker_.CalledOnValidThread();
50 task_queue_manager_.reset(); 64 task_queue_manager_.reset();
51 } 65 }
52 66
53 scoped_refptr<base::SingleThreadTaskRunner> 67 scoped_refptr<base::SingleThreadTaskRunner>
54 RendererSchedulerImpl::DefaultTaskRunner() { 68 RendererSchedulerImpl::DefaultTaskRunner() {
55 main_thread_checker_.CalledOnValidThread(); 69 main_thread_checker_.CalledOnValidThread();
56 return default_task_runner_; 70 return default_task_runner_;
57 } 71 }
58 72
59 scoped_refptr<base::SingleThreadTaskRunner> 73 scoped_refptr<base::SingleThreadTaskRunner>
60 RendererSchedulerImpl::CompositorTaskRunner() { 74 RendererSchedulerImpl::CompositorTaskRunner() {
61 main_thread_checker_.CalledOnValidThread(); 75 main_thread_checker_.CalledOnValidThread();
62 return compositor_task_runner_; 76 return compositor_task_runner_;
63 } 77 }
64 78
65 scoped_refptr<SingleThreadIdleTaskRunner> 79 scoped_refptr<SingleThreadIdleTaskRunner>
66 RendererSchedulerImpl::IdleTaskRunner() { 80 RendererSchedulerImpl::IdleTaskRunner() {
67 main_thread_checker_.CalledOnValidThread(); 81 main_thread_checker_.CalledOnValidThread();
68 return idle_task_runner_; 82 return idle_task_runner_;
69 } 83 }
70 84
71 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { 85 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
86 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
87 "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue());
72 main_thread_checker_.CalledOnValidThread(); 88 main_thread_checker_.CalledOnValidThread();
73 if (!task_queue_manager_) 89 if (!task_queue_manager_)
74 return; 90 return;
75 91
76 EndIdlePeriod(); 92 EndIdlePeriod();
77 estimated_next_frame_begin_ = args.frame_time + args.interval; 93 estimated_next_frame_begin_ = args.frame_time + args.interval;
78 } 94 }
79 95
80 void RendererSchedulerImpl::DidCommitFrameToCompositor() { 96 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
97 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
98 "RendererSchedulerImpl::DidCommitFrameToCompositor");
81 main_thread_checker_.CalledOnValidThread(); 99 main_thread_checker_.CalledOnValidThread();
82 if (!task_queue_manager_) 100 if (!task_queue_manager_)
83 return; 101 return;
84 102
85 base::TimeTicks now(Now()); 103 base::TimeTicks now(Now());
86 if (now < estimated_next_frame_begin_) { 104 if (now < estimated_next_frame_begin_) {
87 StartIdlePeriod(); 105 StartIdlePeriod();
88 control_task_runner_->PostDelayedTask(FROM_HERE, end_idle_period_closure_, 106 control_task_runner_->PostDelayedTask(FROM_HERE, end_idle_period_closure_,
89 estimated_next_frame_begin_ - now); 107 estimated_next_frame_begin_ - now);
90 } 108 }
91 } 109 }
92 110
93 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( 111 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread(
94 blink::WebInputEvent::Type type) { 112 blink::WebInputEvent::Type type) {
113 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
114 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread");
95 // Ignore mouse events because on windows these can very frequent. 115 // Ignore mouse events because on windows these can very frequent.
96 // Ignore keyboard events because it doesn't really make sense to enter 116 // Ignore keyboard events because it doesn't really make sense to enter
97 // compositor priority for them. 117 // compositor priority for them.
98 if (blink::WebInputEvent::isMouseEventType(type) || 118 if (blink::WebInputEvent::isMouseEventType(type) ||
99 blink::WebInputEvent::isKeyboardEventType(type)) { 119 blink::WebInputEvent::isKeyboardEventType(type)) {
100 return; 120 return;
101 } 121 }
102 UpdateForInputEvent(); 122 UpdateForInputEvent();
103 } 123 }
104 124
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 control_task_runner_->PostDelayedTask(FROM_HERE, update_policy_closure_, 173 control_task_runner_->PostDelayedTask(FROM_HERE, update_policy_closure_,
154 delay); 174 delay);
155 } 175 }
156 176
157 void RendererSchedulerImpl::UpdatePolicy() { 177 void RendererSchedulerImpl::UpdatePolicy() {
158 main_thread_checker_.CalledOnValidThread(); 178 main_thread_checker_.CalledOnValidThread();
159 if (!task_queue_manager_) 179 if (!task_queue_manager_)
160 return; 180 return;
161 181
162 base::AutoLock lock(incoming_signals_lock_); 182 base::AutoLock lock(incoming_signals_lock_);
183 base::TimeTicks now;
163 policy_may_need_update_.SetLocked(false); 184 policy_may_need_update_.SetLocked(false);
164 185
165 Policy new_policy = NORMAL_PRIORITY_POLICY; 186 Policy new_policy = NORMAL_PRIORITY_POLICY;
166 if (!last_input_time_.is_null()) { 187 if (!last_input_time_.is_null()) {
167 base::TimeDelta compositor_priority_duration = 188 base::TimeDelta compositor_priority_duration =
168 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis); 189 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
169 base::TimeTicks compositor_priority_end(last_input_time_ + 190 base::TimeTicks compositor_priority_end(last_input_time_ +
170 compositor_priority_duration); 191 compositor_priority_duration);
171 base::TimeTicks now(Now()); 192 now = Now();
172 if (compositor_priority_end > now) { 193 if (compositor_priority_end > now) {
173 PostUpdatePolicyOnControlRunner(compositor_priority_end - now); 194 PostUpdatePolicyOnControlRunner(compositor_priority_end - now);
174 new_policy = COMPOSITOR_PRIORITY_POLICY; 195 new_policy = COMPOSITOR_PRIORITY_POLICY;
175 } else { 196 } else {
176 // Null out last_input_time_ to ensure 197 // Null out last_input_time_ to ensure
177 // DidReceiveInputEventOnCompositorThread will post an 198 // DidReceiveInputEventOnCompositorThread will post an
178 // UpdatePolicy task when it's next called. 199 // UpdatePolicy task when it's next called.
179 last_input_time_ = base::TimeTicks(); 200 last_input_time_ = base::TimeTicks();
180 } 201 }
181 } 202 }
182 203
183 if (new_policy == current_policy_) 204 if (new_policy == current_policy_)
184 return; 205 return;
185 206
186 switch (new_policy) { 207 switch (new_policy) {
187 case COMPOSITOR_PRIORITY_POLICY: 208 case COMPOSITOR_PRIORITY_POLICY:
188 renderer_task_queue_selector_->SetQueuePriority( 209 renderer_task_queue_selector_->SetQueuePriority(
189 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 210 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
190 break; 211 break;
191 case NORMAL_PRIORITY_POLICY: 212 case NORMAL_PRIORITY_POLICY:
192 renderer_task_queue_selector_->SetQueuePriority( 213 renderer_task_queue_selector_->SetQueuePriority(
193 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); 214 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
194 break; 215 break;
195 } 216 }
196 current_policy_ = new_policy; 217 current_policy_ = new_policy;
218
219 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
220 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
221 this, AsValueLocked(now));
222 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
223 "RendererScheduler.policy", current_policy_);
197 } 224 }
198 225
199 void RendererSchedulerImpl::StartIdlePeriod() { 226 void RendererSchedulerImpl::StartIdlePeriod() {
227 TRACE_EVENT_ASYNC_BEGIN0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
228 "RendererSchedulerIdlePeriod", this);
200 main_thread_checker_.CalledOnValidThread(); 229 main_thread_checker_.CalledOnValidThread();
201 renderer_task_queue_selector_->EnableQueue( 230 renderer_task_queue_selector_->EnableQueue(
202 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); 231 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
203 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); 232 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
204 } 233 }
205 234
206 void RendererSchedulerImpl::EndIdlePeriod() { 235 void RendererSchedulerImpl::EndIdlePeriod() {
236 TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
237 "RendererSchedulerIdlePeriod", this);
207 main_thread_checker_.CalledOnValidThread(); 238 main_thread_checker_.CalledOnValidThread();
208 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); 239 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
209 } 240 }
210 241
211 base::TimeTicks RendererSchedulerImpl::Now() const { 242 base::TimeTicks RendererSchedulerImpl::Now() const {
212 return gfx::FrameTime::Now(); 243 return gfx::FrameTime::Now();
213 } 244 }
214 245
215 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag( 246 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
216 base::Lock* write_lock_) 247 base::Lock* write_lock_)
217 : flag_(false), write_lock_(write_lock_) { 248 : flag_(false), write_lock_(write_lock_) {
218 } 249 }
219 250
220 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() { 251 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() {
221 } 252 }
222 253
223 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetLocked(bool value) { 254 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetLocked(bool value) {
224 write_lock_->AssertAcquired(); 255 write_lock_->AssertAcquired();
225 base::subtle::Release_Store(&flag_, value); 256 base::subtle::Release_Store(&flag_, value);
226 } 257 }
227 258
228 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const { 259 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
229 thread_checker_.CalledOnValidThread(); 260 thread_checker_.CalledOnValidThread();
230 return base::subtle::Acquire_Load(&flag_) != 0; 261 return base::subtle::Acquire_Load(&flag_) != 0;
231 } 262 }
263
264 // static
265 const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
266 switch (queue_id) {
267 case DEFAULT_TASK_QUEUE:
268 return "default_tq";
269 case COMPOSITOR_TASK_QUEUE:
270 return "compositor_tq";
271 case IDLE_TASK_QUEUE:
272 return "idle_tq";
273 case CONTROL_TASK_QUEUE:
274 return "control_tq";
275 default:
276 NOTREACHED();
277 return nullptr;
278 }
279 }
280
281 // static
282 const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
283 switch (policy) {
284 case NORMAL_PRIORITY_POLICY:
285 return "normal";
286 case COMPOSITOR_PRIORITY_POLICY:
287 return "compositor";
288 default:
289 NOTREACHED();
290 return nullptr;
291 }
292 }
293
294 scoped_refptr<base::debug::ConvertableToTraceFormat>
295 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
296 main_thread_checker_.CalledOnValidThread();
297 incoming_signals_lock_.AssertAcquired();
298
299 if (optional_now.is_null())
300 optional_now = Now();
301 scoped_refptr<base::debug::TracedValue> state =
302 new base::debug::TracedValue();
303
304 state->SetString("current_policy", PolicyToString(current_policy_));
305 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
306 state->SetDouble("last_input_time",
307 (last_input_time_ - base::TimeTicks()).InMillisecondsF());
308 state->SetDouble(
309 "estimated_next_frame_begin",
310 (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF());
311
312 return state;
313 }
314
232 } // namespace content 315 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/scheduler/renderer_scheduler_impl.h ('k') | content/renderer/scheduler/renderer_task_queue_selector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698