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

Side by Side Diff: cc/scheduler/scheduler.cc

Issue 218633010: cc: Handle retroactive BeginFrames in the Scheduler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@compositorVsyncDisable
Patch Set: sami's comments; rebase Created 6 years, 8 months 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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 "cc/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "cc/debug/devtools_instrumentation.h" 11 #include "cc/debug/devtools_instrumentation.h"
12 #include "cc/debug/traced_value.h" 12 #include "cc/debug/traced_value.h"
13 #include "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
14 14
15 namespace cc { 15 namespace cc {
16 16
17 Scheduler::Scheduler( 17 Scheduler::Scheduler(
18 SchedulerClient* client, 18 SchedulerClient* client,
19 const SchedulerSettings& scheduler_settings, 19 const SchedulerSettings& scheduler_settings,
20 int layer_tree_host_id, 20 int layer_tree_host_id,
21 const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner) 21 const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner)
22 : settings_(scheduler_settings), 22 : settings_(scheduler_settings),
23 client_(client), 23 client_(client),
24 layer_tree_host_id_(layer_tree_host_id), 24 layer_tree_host_id_(layer_tree_host_id),
25 impl_task_runner_(impl_task_runner), 25 impl_task_runner_(impl_task_runner),
26 last_set_needs_begin_impl_frame_(false), 26 last_set_needs_begin_frame_(false),
27 begin_retro_frame_posted_(false),
27 state_machine_(scheduler_settings), 28 state_machine_(scheduler_settings),
28 inside_process_scheduled_actions_(false), 29 inside_process_scheduled_actions_(false),
29 inside_action_(SchedulerStateMachine::ACTION_NONE), 30 inside_action_(SchedulerStateMachine::ACTION_NONE),
30 weak_factory_(this) { 31 weak_factory_(this) {
31 DCHECK(client_); 32 DCHECK(client_);
32 DCHECK(!state_machine_.BeginImplFrameNeeded()); 33 DCHECK(!state_machine_.BeginFrameNeeded());
33 if (settings_.main_frame_before_activation_enabled) { 34 if (settings_.main_frame_before_activation_enabled) {
34 DCHECK(settings_.main_frame_before_draw_enabled); 35 DCHECK(settings_.main_frame_before_draw_enabled);
35 } 36 }
36 37
38 begin_retro_frame_closure_ =
39 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
37 begin_impl_frame_deadline_closure_ = base::Bind( 40 begin_impl_frame_deadline_closure_ = base::Bind(
38 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 41 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
39 poll_for_draw_triggers_closure_ = base::Bind( 42 poll_for_draw_triggers_closure_ = base::Bind(
40 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 43 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
41 advance_commit_state_closure_ = base::Bind( 44 advance_commit_state_closure_ = base::Bind(
42 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 45 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
43 } 46 }
44 47
45 Scheduler::~Scheduler() {} 48 Scheduler::~Scheduler() {}
46 49
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 ProcessScheduledActions(); 119 ProcessScheduledActions();
117 } 120 }
118 121
119 void Scheduler::DidManageTiles() { 122 void Scheduler::DidManageTiles() {
120 state_machine_.DidManageTiles(); 123 state_machine_.DidManageTiles();
121 } 124 }
122 125
123 void Scheduler::DidLoseOutputSurface() { 126 void Scheduler::DidLoseOutputSurface() {
124 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 127 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
125 state_machine_.DidLoseOutputSurface(); 128 state_machine_.DidLoseOutputSurface();
126 last_set_needs_begin_impl_frame_ = false; 129 last_set_needs_begin_frame_ = false;
130 begin_retro_frame_args_.clear();
127 ProcessScheduledActions(); 131 ProcessScheduledActions();
128 } 132 }
129 133
130 void Scheduler::DidCreateAndInitializeOutputSurface() { 134 void Scheduler::DidCreateAndInitializeOutputSurface() {
131 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 135 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
132 DCHECK(!last_set_needs_begin_impl_frame_); 136 DCHECK(!last_set_needs_begin_frame_);
133 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 137 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
134 state_machine_.DidCreateAndInitializeOutputSurface(); 138 state_machine_.DidCreateAndInitializeOutputSurface();
135 ProcessScheduledActions(); 139 ProcessScheduledActions();
136 } 140 }
137 141
138 void Scheduler::NotifyBeginMainFrameStarted() { 142 void Scheduler::NotifyBeginMainFrameStarted() {
139 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 143 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
140 state_machine_.NotifyBeginMainFrameStarted(); 144 state_machine_.NotifyBeginMainFrameStarted();
141 } 145 }
142 146
143 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 147 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
144 if (!last_set_needs_begin_impl_frame_ || 148 if (!last_set_needs_begin_frame_ ||
145 last_begin_impl_frame_args_.interval <= base::TimeDelta()) 149 begin_impl_frame_args_.interval <= base::TimeDelta())
146 return base::TimeTicks(); 150 return base::TimeTicks();
147 151
148 base::TimeTicks now = gfx::FrameTime::Now(); 152 base::TimeTicks now = gfx::FrameTime::Now();
149 base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time, 153 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
150 last_begin_impl_frame_args_.deadline); 154 begin_impl_frame_args_.deadline);
151 int64 intervals = 155 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
152 1 + ((now - timebase) / last_begin_impl_frame_args_.interval); 156 return timebase + (begin_impl_frame_args_.interval * intervals);
153 return timebase + (last_begin_impl_frame_args_.interval * intervals);
154 } 157 }
155 158
156 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 159 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
157 return last_begin_impl_frame_args_.frame_time; 160 return begin_impl_frame_args_.frame_time;
158 } 161 }
159 162
160 void Scheduler::SetupNextBeginImplFrameIfNeeded() { 163 void Scheduler::SetupNextBeginFrameIfNeeded() {
161 bool needs_begin_impl_frame = 164 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
162 state_machine_.BeginImplFrameNeeded();
163 165
164 bool at_end_of_deadline = 166 bool at_end_of_deadline =
165 state_machine_.begin_impl_frame_state() == 167 state_machine_.begin_impl_frame_state() ==
166 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 168 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
167 169
168 bool should_call_set_needs_begin_impl_frame = 170 bool should_call_set_needs_begin_frame =
169 // Always request the BeginImplFrame immediately if it wasn't needed 171 // Always request the BeginFrame immediately if it wasn't needed before.
170 // before. 172 (needs_begin_frame && !last_set_needs_begin_frame_) ||
171 (needs_begin_impl_frame && !last_set_needs_begin_impl_frame_) || 173 // We always need to explicitly request our next BeginFrame.
172 // We always need to explicitly request our next BeginImplFrame.
173 at_end_of_deadline; 174 at_end_of_deadline;
174 175
175 if (should_call_set_needs_begin_impl_frame) { 176 if (should_call_set_needs_begin_frame) {
176 client_->SetNeedsBeginImplFrame(needs_begin_impl_frame); 177 client_->SetNeedsBeginFrame(needs_begin_frame);
177 last_set_needs_begin_impl_frame_ = needs_begin_impl_frame; 178 last_set_needs_begin_frame_ = needs_begin_frame;
178 } 179 }
179 180
181 // Handle retroactive BeginFrames.
182 if (needs_begin_frame)
183 PostBeginRetroFrameIfNeeded();
184
180 bool needs_advance_commit_state_timer = false; 185 bool needs_advance_commit_state_timer = false;
181 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 186 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
182 // aren't expecting any more BeginImplFrames. This should only be needed by 187 // aren't expecting any more BeginFrames. This should only be needed by
183 // the synchronous compositor when BeginImplFrameNeeded is false. 188 // the synchronous compositor when BeginFrameNeeded is false.
184 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 189 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
185 DCHECK(!state_machine_.SupportsProactiveBeginImplFrame()); 190 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
186 DCHECK(!needs_begin_impl_frame); 191 DCHECK(!needs_begin_frame);
187 if (poll_for_draw_triggers_task_.IsCancelled()) { 192 if (poll_for_draw_triggers_task_.IsCancelled()) {
188 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); 193 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
189 base::TimeDelta delay = last_begin_impl_frame_args_.IsValid() 194 base::TimeDelta delay = begin_impl_frame_args_.IsValid()
190 ? last_begin_impl_frame_args_.interval 195 ? begin_impl_frame_args_.interval
191 : BeginFrameArgs::DefaultInterval(); 196 : BeginFrameArgs::DefaultInterval();
192 impl_task_runner_->PostDelayedTask( 197 impl_task_runner_->PostDelayedTask(
193 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); 198 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
194 } 199 }
195 } else { 200 } else {
196 poll_for_draw_triggers_task_.Cancel(); 201 poll_for_draw_triggers_task_.Cancel();
197 202
198 // At this point we'd prefer to advance through the commit flow by 203 // At this point we'd prefer to advance through the commit flow by
199 // drawing a frame, however it's possible that the frame rate controller 204 // drawing a frame, however it's possible that the frame rate controller
200 // will not give us a BeginImplFrame until the commit completes. See 205 // will not give us a BeginFrame until the commit completes. See
201 // crbug.com/317430 for an example of a swap ack being held on commit. Thus 206 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
202 // we set a repeating timer to poll on ProcessScheduledActions until we 207 // we set a repeating timer to poll on ProcessScheduledActions until we
203 // successfully reach BeginImplFrame. Synchronous compositor does not use 208 // successfully reach BeginFrame. Synchronous compositor does not use
204 // frame rate controller or have the circular wait in the bug. 209 // frame rate controller or have the circular wait in the bug.
205 if (IsBeginMainFrameSentOrStarted() && 210 if (IsBeginMainFrameSentOrStarted() &&
206 !settings_.using_synchronous_renderer_compositor) { 211 !settings_.using_synchronous_renderer_compositor) {
207 needs_advance_commit_state_timer = true; 212 needs_advance_commit_state_timer = true;
208 } 213 }
209 } 214 }
210 215
211 if (needs_advance_commit_state_timer) { 216 if (needs_advance_commit_state_timer) {
212 if (advance_commit_state_task_.IsCancelled() && 217 if (advance_commit_state_task_.IsCancelled() &&
213 last_begin_impl_frame_args_.IsValid()) { 218 begin_impl_frame_args_.IsValid()) {
214 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 219 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
215 // set the interval to twice the interval from the previous frame. 220 // set the interval to twice the interval from the previous frame.
216 advance_commit_state_task_.Reset(advance_commit_state_closure_); 221 advance_commit_state_task_.Reset(advance_commit_state_closure_);
217 impl_task_runner_->PostDelayedTask( 222 impl_task_runner_->PostDelayedTask(FROM_HERE,
218 FROM_HERE, 223 advance_commit_state_task_.callback(),
219 advance_commit_state_task_.callback(), 224 begin_impl_frame_args_.interval * 2);
220 last_begin_impl_frame_args_.interval * 2);
221 } 225 }
222 } else { 226 } else {
223 advance_commit_state_task_.Cancel(); 227 advance_commit_state_task_.Cancel();
224 } 228 }
225 } 229 }
226 230
231 void Scheduler::PostBeginRetroFrameIfNeeded() {
232 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
233 return;
234
235 // begin_retro_frame_args_ should always be empty for the
236 // synchronous compositor.
237 DCHECK(!settings_.using_synchronous_renderer_compositor);
238
239 if (state_machine_.begin_impl_frame_state() !=
240 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
241 return;
242
243 begin_retro_frame_posted_ = true;
244 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
245 }
246
247 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
248 if (settings_.using_synchronous_renderer_compositor ||
brianderson 2014/04/07 18:02:22 This is where I prevent WebView from using the ret
249 (last_set_needs_begin_frame_ && begin_retro_frame_args_.empty() &&
250 state_machine_.begin_impl_frame_state() ==
251 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)) {
252 BeginImplFrame(args);
253 } else {
254 begin_retro_frame_args_.push_back(args);
255 TRACE_EVENT_INSTANT0(
256 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
257 }
258 }
259
260 void Scheduler::BeginRetroFrame() {
261 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
262 DCHECK(begin_retro_frame_posted_);
263 DCHECK(!begin_retro_frame_args_.empty());
264
265 // Discard expired BeginRetroFrames
266 base::TimeTicks now = gfx::FrameTime::Now();
267 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
268 while (!begin_retro_frame_args_.empty() &&
269 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
270 draw_duration_estimate)) {
271 begin_retro_frame_args_.pop_front();
272 }
273
274 if (begin_retro_frame_args_.empty()) {
275 TRACE_EVENT_INSTANT0(
276 "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD);
277 } else {
278 BeginImplFrame(begin_retro_frame_args_.front());
279 begin_retro_frame_args_.pop_front();
280 }
281
282 begin_retro_frame_posted_ = false;
283 }
284
227 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 285 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
228 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); 286 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame");
229 DCHECK(state_machine_.begin_impl_frame_state() == 287 DCHECK(state_machine_.begin_impl_frame_state() ==
230 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 288 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
231 DCHECK(state_machine_.HasInitializedOutputSurface()); 289 DCHECK(state_machine_.HasInitializedOutputSurface());
232 290
233 advance_commit_state_task_.Cancel(); 291 advance_commit_state_task_.Cancel();
234 292
235 last_begin_impl_frame_args_ = args; 293 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
236 last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 294 begin_impl_frame_args_ = args;
295 begin_impl_frame_args_.deadline -= draw_duration_estimate;
237 296
238 if (!state_machine_.smoothness_takes_priority() && 297 if (!state_machine_.smoothness_takes_priority() &&
239 state_machine_.MainThreadIsInHighLatencyMode() && 298 state_machine_.MainThreadIsInHighLatencyMode() &&
240 CanCommitAndActivateBeforeDeadline()) { 299 CanCommitAndActivateBeforeDeadline()) {
241 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 300 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
242 } 301 }
243 302
244 state_machine_.OnBeginImplFrame(last_begin_impl_frame_args_); 303 client_->WillBeginImplFrame(begin_impl_frame_args_);
304 state_machine_.OnBeginImplFrame(begin_impl_frame_args_);
245 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 305 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
246 306
247 ProcessScheduledActions(); 307 ProcessScheduledActions();
248 308
249 if (!state_machine_.HasInitializedOutputSurface()) 309 if (!state_machine_.HasInitializedOutputSurface())
250 return; 310 return;
251 311
252 state_machine_.OnBeginImplFrameDeadlinePending(); 312 state_machine_.OnBeginImplFrameDeadlinePending();
253 base::TimeTicks adjusted_deadline = AdjustedBeginImplFrameDeadline(); 313 ScheduleBeginImplFrameDeadline(
254 ScheduleBeginImplFrameDeadline(adjusted_deadline); 314 AdjustedBeginImplFrameDeadline(args, draw_duration_estimate));
255 } 315 }
256 316
257 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { 317 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline(
318 const BeginFrameArgs& args,
319 base::TimeDelta draw_duration_estimate) const {
258 if (settings_.using_synchronous_renderer_compositor) { 320 if (settings_.using_synchronous_renderer_compositor) {
259 // The synchronous compositor needs to draw right away. 321 // The synchronous compositor needs to draw right away.
260 return base::TimeTicks(); 322 return base::TimeTicks();
261 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { 323 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
262 // We are ready to draw a new active tree immediately. 324 // We are ready to draw a new active tree immediately.
263 return base::TimeTicks(); 325 return base::TimeTicks();
264 } else if (state_machine_.needs_redraw()) { 326 } else if (state_machine_.needs_redraw()) {
265 // We have an animation or fast input path on the impl thread that wants 327 // We have an animation or fast input path on the impl thread that wants
266 // to draw, so don't wait too long for a new active tree. 328 // to draw, so don't wait too long for a new active tree.
267 return last_begin_impl_frame_args_.deadline; 329 return args.deadline - draw_duration_estimate;
268 } else { 330 } else {
269 // The impl thread doesn't have anything it wants to draw and we are just 331 // The impl thread doesn't have anything it wants to draw and we are just
270 // waiting for a new active tree, so post the deadline for the next 332 // waiting for a new active tree, so post the deadline for the next
271 // expected BeginImplFrame start. This allows us to draw immediately when 333 // expected BeginImplFrame start. This allows us to draw immediately when
272 // there is a new active tree, instead of waiting for the next 334 // there is a new active tree, instead of waiting for the next
273 // BeginImplFrame. 335 // BeginImplFrame.
274 // TODO(brianderson): Handle long deadlines (that are past the next frame's 336 // TODO(brianderson): Handle long deadlines (that are past the next frame's
275 // frame time) properly instead of using this hack. 337 // frame time) properly instead of using this hack.
276 return last_begin_impl_frame_args_.frame_time + 338 return args.frame_time + args.interval;
277 last_begin_impl_frame_args_.interval;
278 } 339 }
279 } 340 }
280 341
281 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { 342 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
282 if (settings_.using_synchronous_renderer_compositor) { 343 if (settings_.using_synchronous_renderer_compositor) {
283 // The synchronous renderer compositor has to make its GL calls 344 // The synchronous renderer compositor has to make its GL calls
284 // within this call. 345 // within this call.
285 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks 346 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
286 // so the sychronous renderer compositor can take advantage of splitting 347 // so the sychronous renderer compositor can take advantage of splitting
287 // up the BeginImplFrame and deadline as well. 348 // up the BeginImplFrame and deadline as well.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 break; 464 break;
404 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 465 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
405 client_->ScheduledActionAcquireLayerTexturesForMainThread(); 466 client_->ScheduledActionAcquireLayerTexturesForMainThread();
406 break; 467 break;
407 case SchedulerStateMachine::ACTION_MANAGE_TILES: 468 case SchedulerStateMachine::ACTION_MANAGE_TILES:
408 client_->ScheduledActionManageTiles(); 469 client_->ScheduledActionManageTiles();
409 break; 470 break;
410 } 471 }
411 } while (action != SchedulerStateMachine::ACTION_NONE); 472 } while (action != SchedulerStateMachine::ACTION_NONE);
412 473
413 SetupNextBeginImplFrameIfNeeded(); 474 SetupNextBeginFrameIfNeeded();
414 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 475 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
415 476
416 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { 477 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
417 DCHECK(!settings_.using_synchronous_renderer_compositor); 478 DCHECK(!settings_.using_synchronous_renderer_compositor);
418 ScheduleBeginImplFrameDeadline(base::TimeTicks()); 479 ScheduleBeginImplFrameDeadline(base::TimeTicks());
419 } 480 }
420 } 481 }
421 482
422 bool Scheduler::WillDrawIfNeeded() const { 483 bool Scheduler::WillDrawIfNeeded() const {
423 return !state_machine_.PendingDrawsShouldBeAborted(); 484 return !state_machine_.PendingDrawsShouldBeAborted();
424 } 485 }
425 486
426 scoped_ptr<base::Value> Scheduler::StateAsValue() const { 487 scoped_ptr<base::Value> Scheduler::StateAsValue() const {
427 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 488 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
428 state->Set("state_machine", state_machine_.AsValue().release()); 489 state->Set("state_machine", state_machine_.AsValue().release());
429 490
430 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); 491 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue);
431 scheduler_state->SetDouble( 492 scheduler_state->SetDouble(
432 "time_until_anticipated_draw_time_ms", 493 "time_until_anticipated_draw_time_ms",
433 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); 494 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
434 scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_", 495 scheduler_state->SetBoolean("last_set_needs_begin_frame_",
435 last_set_needs_begin_impl_frame_); 496 last_set_needs_begin_frame_);
436 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", 497 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
437 !begin_impl_frame_deadline_task_.IsCancelled()); 498 !begin_impl_frame_deadline_task_.IsCancelled());
438 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", 499 scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
439 !poll_for_draw_triggers_task_.IsCancelled()); 500 !poll_for_draw_triggers_task_.IsCancelled());
440 scheduler_state->SetBoolean("advance_commit_state_task_", 501 scheduler_state->SetBoolean("advance_commit_state_task_",
441 !advance_commit_state_task_.IsCancelled()); 502 !advance_commit_state_task_.IsCancelled());
442 state->Set("scheduler_state", scheduler_state.release()); 503 state->Set("scheduler_state", scheduler_state.release());
443 504
444 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); 505 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue);
445 client_state->SetDouble("draw_duration_estimate_ms", 506 client_state->SetDouble("draw_duration_estimate_ms",
446 client_->DrawDurationEstimate().InMillisecondsF()); 507 client_->DrawDurationEstimate().InMillisecondsF());
447 client_state->SetDouble( 508 client_state->SetDouble(
448 "begin_main_frame_to_commit_duration_estimate_ms", 509 "begin_main_frame_to_commit_duration_estimate_ms",
449 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); 510 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
450 client_state->SetDouble( 511 client_state->SetDouble(
451 "commit_to_activate_duration_estimate_ms", 512 "commit_to_activate_duration_estimate_ms",
452 client_->CommitToActivateDurationEstimate().InMillisecondsF()); 513 client_->CommitToActivateDurationEstimate().InMillisecondsF());
453 state->Set("client_state", client_state.release()); 514 state->Set("client_state", client_state.release());
454 return state.PassAs<base::Value>(); 515 return state.PassAs<base::Value>();
455 } 516 }
456 517
457 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { 518 bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
458 // Check if the main thread computation and commit can be finished before the 519 // Check if the main thread computation and commit can be finished before the
459 // impl thread's deadline. 520 // impl thread's deadline.
460 base::TimeTicks estimated_draw_time = 521 base::TimeTicks estimated_draw_time =
461 last_begin_impl_frame_args_.frame_time + 522 begin_impl_frame_args_.frame_time +
462 client_->BeginMainFrameToCommitDurationEstimate() + 523 client_->BeginMainFrameToCommitDurationEstimate() +
463 client_->CommitToActivateDurationEstimate(); 524 client_->CommitToActivateDurationEstimate();
464 525
465 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 526 TRACE_EVENT2(
466 "CanCommitAndActivateBeforeDeadline", 527 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
467 "time_left_after_drawing_ms", 528 "CanCommitAndActivateBeforeDeadline",
468 (last_begin_impl_frame_args_.deadline - estimated_draw_time) 529 "time_left_after_drawing_ms",
469 .InMillisecondsF(), 530 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
470 "state", 531 "state",
471 TracedValue::FromValue(StateAsValue().release())); 532 TracedValue::FromValue(StateAsValue().release()));
472 533
473 return estimated_draw_time < last_begin_impl_frame_args_.deadline; 534 return estimated_draw_time < begin_impl_frame_args_.deadline;
474 } 535 }
475 536
476 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 537 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
477 return (state_machine_.commit_state() == 538 return (state_machine_.commit_state() ==
478 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 539 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
479 state_machine_.commit_state() == 540 state_machine_.commit_state() ==
480 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 541 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
481 } 542 }
482 543
483 } // namespace cc 544 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698