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

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: Small reorganization. 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() {
112 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
113 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread");
94 // TODO(rmcilroy): Decide whether only a subset of input events should trigger 114 // TODO(rmcilroy): Decide whether only a subset of input events should trigger
95 // compositor priority policy - http://crbug.com/429814. 115 // compositor priority policy - http://crbug.com/429814.
96 base::AutoLock lock(incoming_signals_lock_); 116 base::AutoLock lock(incoming_signals_lock_);
97 if (last_input_time_.is_null()) { 117 if (last_input_time_.is_null()) {
98 // Update scheduler policy if should start a new compositor policy mode. 118 // Update scheduler policy if should start a new compositor policy mode.
99 policy_may_need_update_.SetLocked(true); 119 policy_may_need_update_.SetLocked(true);
100 PostUpdatePolicyOnControlRunner(base::TimeDelta()); 120 PostUpdatePolicyOnControlRunner(base::TimeDelta());
101 } 121 }
102 last_input_time_ = Now(); 122 last_input_time_ = Now();
103 } 123 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 control_task_runner_->PostDelayedTask(FROM_HERE, update_policy_closure_, 159 control_task_runner_->PostDelayedTask(FROM_HERE, update_policy_closure_,
140 delay); 160 delay);
141 } 161 }
142 162
143 void RendererSchedulerImpl::UpdatePolicy() { 163 void RendererSchedulerImpl::UpdatePolicy() {
144 main_thread_checker_.CalledOnValidThread(); 164 main_thread_checker_.CalledOnValidThread();
145 if (!task_queue_manager_) 165 if (!task_queue_manager_)
146 return; 166 return;
147 167
148 base::AutoLock lock(incoming_signals_lock_); 168 base::AutoLock lock(incoming_signals_lock_);
169 base::TimeTicks now;
149 policy_may_need_update_.SetLocked(false); 170 policy_may_need_update_.SetLocked(false);
150 171
151 Policy new_policy = NORMAL_PRIORITY_POLICY; 172 Policy new_policy = NORMAL_PRIORITY_POLICY;
152 if (!last_input_time_.is_null()) { 173 if (!last_input_time_.is_null()) {
153 base::TimeDelta compositor_priority_duration = 174 base::TimeDelta compositor_priority_duration =
154 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis); 175 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
155 base::TimeTicks compositor_priority_end(last_input_time_ + 176 base::TimeTicks compositor_priority_end(last_input_time_ +
156 compositor_priority_duration); 177 compositor_priority_duration);
157 base::TimeTicks now(Now()); 178 now = Now();
158 if (compositor_priority_end > now) { 179 if (compositor_priority_end > now) {
159 PostUpdatePolicyOnControlRunner(compositor_priority_end - now); 180 PostUpdatePolicyOnControlRunner(compositor_priority_end - now);
160 new_policy = COMPOSITOR_PRIORITY_POLICY; 181 new_policy = COMPOSITOR_PRIORITY_POLICY;
161 } else { 182 } else {
162 // Null out last_input_time_ to ensure 183 // Null out last_input_time_ to ensure
163 // DidReceiveInputEventOnCompositorThread will post an 184 // DidReceiveInputEventOnCompositorThread will post an
164 // UpdatePolicy task when it's next called. 185 // UpdatePolicy task when it's next called.
165 last_input_time_ = base::TimeTicks(); 186 last_input_time_ = base::TimeTicks();
166 } 187 }
167 } 188 }
168 189
169 if (new_policy == current_policy_) 190 if (new_policy == current_policy_)
170 return; 191 return;
171 192
172 switch (new_policy) { 193 switch (new_policy) {
173 case COMPOSITOR_PRIORITY_POLICY: 194 case COMPOSITOR_PRIORITY_POLICY:
174 renderer_task_queue_selector_->SetQueuePriority( 195 renderer_task_queue_selector_->SetQueuePriority(
175 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 196 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
176 break; 197 break;
177 case NORMAL_PRIORITY_POLICY: 198 case NORMAL_PRIORITY_POLICY:
178 renderer_task_queue_selector_->SetQueuePriority( 199 renderer_task_queue_selector_->SetQueuePriority(
179 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); 200 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY);
180 break; 201 break;
181 } 202 }
182 current_policy_ = new_policy; 203 current_policy_ = new_policy;
204
205 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
206 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
207 this, AsValueLocked(now));
208 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
209 "RendererScheduler.policy", current_policy_);
183 } 210 }
184 211
185 void RendererSchedulerImpl::StartIdlePeriod() { 212 void RendererSchedulerImpl::StartIdlePeriod() {
213 TRACE_EVENT_ASYNC_BEGIN0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
214 "RendererSchedulerIdlePeriod", this);
186 main_thread_checker_.CalledOnValidThread(); 215 main_thread_checker_.CalledOnValidThread();
187 renderer_task_queue_selector_->EnableQueue( 216 renderer_task_queue_selector_->EnableQueue(
188 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); 217 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
189 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE); 218 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
190 } 219 }
191 220
192 void RendererSchedulerImpl::EndIdlePeriod() { 221 void RendererSchedulerImpl::EndIdlePeriod() {
222 TRACE_EVENT_ASYNC_END0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
223 "RendererSchedulerIdlePeriod", this);
193 main_thread_checker_.CalledOnValidThread(); 224 main_thread_checker_.CalledOnValidThread();
194 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE); 225 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
195 } 226 }
196 227
197 base::TimeTicks RendererSchedulerImpl::Now() const { 228 base::TimeTicks RendererSchedulerImpl::Now() const {
198 return gfx::FrameTime::Now(); 229 return gfx::FrameTime::Now();
199 } 230 }
200 231
201 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag( 232 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
202 base::Lock* write_lock_) 233 base::Lock* write_lock_)
203 : flag_(false), write_lock_(write_lock_) { 234 : flag_(false), write_lock_(write_lock_) {
204 } 235 }
205 236
206 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() { 237 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() {
207 } 238 }
208 239
209 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetLocked(bool value) { 240 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetLocked(bool value) {
210 write_lock_->AssertAcquired(); 241 write_lock_->AssertAcquired();
211 base::subtle::Release_Store(&flag_, value); 242 base::subtle::Release_Store(&flag_, value);
212 } 243 }
213 244
214 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const { 245 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
215 thread_checker_.CalledOnValidThread(); 246 thread_checker_.CalledOnValidThread();
216 return base::subtle::Acquire_Load(&flag_) != 0; 247 return base::subtle::Acquire_Load(&flag_) != 0;
217 } 248 }
249
250 // static
251 const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
252 switch (queue_id) {
253 case DEFAULT_TASK_QUEUE:
254 return "default_tq";
255 case COMPOSITOR_TASK_QUEUE:
256 return "compositor_tq";
257 case IDLE_TASK_QUEUE:
258 return "idle_tq";
259 case CONTROL_TASK_QUEUE:
260 return "control_tq";
261 default:
262 NOTREACHED();
263 return nullptr;
264 }
265 }
266
267 // static
268 const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
269 switch (policy) {
270 case NORMAL_PRIORITY_POLICY:
271 return "normal";
272 case COMPOSITOR_PRIORITY_POLICY:
273 return "compositor";
274 default:
275 NOTREACHED();
276 return nullptr;
277 }
278 }
279
280 scoped_refptr<base::debug::ConvertableToTraceFormat>
281 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
282 main_thread_checker_.CalledOnValidThread();
283 incoming_signals_lock_.AssertAcquired();
284
285 if (optional_now.is_null())
286 optional_now = Now();
287 scoped_refptr<base::debug::TracedValue> state =
288 new base::debug::TracedValue();
289
290 state->SetString("current_policy", PolicyToString(current_policy_));
291 state->SetBoolean("has_task_queue_manager", task_queue_manager_.get());
no sievers 2014/11/10 23:15:27 Do you really care about this? The only call site
292 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
293 state->SetDouble("last_input_time",
294 (last_input_time_ - base::TimeTicks()).InMillisecondsF());
295 state->SetDouble(
296 "estimated_next_frame_begin",
297 (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF());
298
299 return state;
300 }
301
218 } // namespace content 302 } // 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