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

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

Issue 2339633003: Reland of cc: Remove frame queuing from the scheduler. (Closed)
Patch Set: expire missed frames in renderer only Created 4 years, 3 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
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 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), 57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), 58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
59 state_machine_(settings), 59 state_machine_(settings),
60 inside_process_scheduled_actions_(false), 60 inside_process_scheduled_actions_(false),
61 inside_action_(SchedulerStateMachine::ACTION_NONE), 61 inside_action_(SchedulerStateMachine::ACTION_NONE),
62 weak_factory_(this) { 62 weak_factory_(this) {
63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); 63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
64 DCHECK(client_); 64 DCHECK(client_);
65 DCHECK(!state_machine_.BeginFrameNeeded()); 65 DCHECK(!state_machine_.BeginFrameNeeded());
66 66
67 begin_retro_frame_closure_ =
68 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
69 begin_impl_frame_deadline_closure_ = base::Bind( 67 begin_impl_frame_deadline_closure_ = base::Bind(
70 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 68 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
71 69
72 SetBeginFrameSource(begin_frame_source); 70 SetBeginFrameSource(begin_frame_source);
73 ProcessScheduledActions(); 71 ProcessScheduledActions();
74 } 72 }
75 73
76 Scheduler::~Scheduler() { 74 Scheduler::~Scheduler() {
77 SetBeginFrameSource(nullptr); 75 SetBeginFrameSource(nullptr);
78 } 76 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 compositor_timing_history_->WillPrepareTiles(); 191 compositor_timing_history_->WillPrepareTiles();
194 } 192 }
195 193
196 void Scheduler::DidPrepareTiles() { 194 void Scheduler::DidPrepareTiles() {
197 compositor_timing_history_->DidPrepareTiles(); 195 compositor_timing_history_->DidPrepareTiles();
198 state_machine_.DidPrepareTiles(); 196 state_machine_.DidPrepareTiles();
199 } 197 }
200 198
201 void Scheduler::DidLoseOutputSurface() { 199 void Scheduler::DidLoseOutputSurface() {
202 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 200 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
203 begin_retro_frame_args_.clear();
204 begin_retro_frame_task_.Cancel();
205 state_machine_.DidLoseOutputSurface(); 201 state_machine_.DidLoseOutputSurface();
206 UpdateCompositorTimingHistoryRecordingEnabled(); 202 UpdateCompositorTimingHistoryRecordingEnabled();
207 ProcessScheduledActions(); 203 ProcessScheduledActions();
208 } 204 }
209 205
210 void Scheduler::DidCreateAndInitializeOutputSurface() { 206 void Scheduler::DidCreateAndInitializeOutputSurface() {
211 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 207 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
212 DCHECK(!observing_begin_frame_source_); 208 DCHECK(!observing_begin_frame_source_);
213 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 209 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
214 state_machine_.DidCreateAndInitializeOutputSurface(); 210 state_machine_.DidCreateAndInitializeOutputSurface();
(...skipping 16 matching lines...) Expand all
231 void Scheduler::BeginImplFrameNotExpectedSoon() { 227 void Scheduler::BeginImplFrameNotExpectedSoon() {
232 compositor_timing_history_->BeginImplFrameNotExpectedSoon(); 228 compositor_timing_history_->BeginImplFrameNotExpectedSoon();
233 229
234 // Tying this to SendBeginMainFrameNotExpectedSoon will have some 230 // Tying this to SendBeginMainFrameNotExpectedSoon will have some
235 // false negatives, but we want to avoid running long idle tasks when 231 // false negatives, but we want to avoid running long idle tasks when
236 // we are actually active. 232 // we are actually active.
237 client_->SendBeginMainFrameNotExpectedSoon(); 233 client_->SendBeginMainFrameNotExpectedSoon();
238 } 234 }
239 235
240 void Scheduler::SetupNextBeginFrameIfNeeded() { 236 void Scheduler::SetupNextBeginFrameIfNeeded() {
241 // Never call SetNeedsBeginFrames if the frame source already has the right 237 if (state_machine_.begin_impl_frame_state() !=
242 // value. 238 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
243 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) { 239 return;
244 if (state_machine_.BeginFrameNeeded()) {
245 // Call AddObserver as soon as possible.
246 observing_begin_frame_source_ = true;
247 if (begin_frame_source_)
248 begin_frame_source_->AddObserver(this);
249 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
250 true);
251 } else if (state_machine_.begin_impl_frame_state() ==
252 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
253 // Call RemoveObserver in between frames only.
254 observing_begin_frame_source_ = false;
255 if (begin_frame_source_)
256 begin_frame_source_->RemoveObserver(this);
257 BeginImplFrameNotExpectedSoon();
258 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
259 false);
260 }
261 } 240 }
262 241
263 PostBeginRetroFrameIfNeeded(); 242 bool needs_begin_frames = state_machine_.BeginFrameNeeded();
243 if (needs_begin_frames && !observing_begin_frame_source_) {
244 observing_begin_frame_source_ = true;
245 if (begin_frame_source_)
246 begin_frame_source_->AddObserver(this);
247 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
248 } else if (!needs_begin_frames && observing_begin_frame_source_) {
249 observing_begin_frame_source_ = false;
250 if (begin_frame_source_)
251 begin_frame_source_->RemoveObserver(this);
252 missed_begin_frame_task_.Cancel();
253 BeginImplFrameNotExpectedSoon();
254 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
255 false);
256 }
264 } 257 }
265 258
266 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { 259 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
267 if (state_machine_.begin_frame_source_paused() == paused) 260 if (state_machine_.begin_frame_source_paused() == paused)
268 return; 261 return;
269 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", 262 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
270 TRACE_EVENT_SCOPE_THREAD, "paused", paused); 263 TRACE_EVENT_SCOPE_THREAD, "paused", paused);
271 state_machine_.SetBeginFrameSourcePaused(paused); 264 state_machine_.SetBeginFrameSourcePaused(paused);
272 ProcessScheduledActions(); 265 ProcessScheduledActions();
273 } 266 }
274 267
275 // BeginFrame is the mechanism that tells us that now is a good time to start 268 // BeginFrame is the mechanism that tells us that now is a good time to start
276 // making a frame. Usually this means that user input for the frame is complete. 269 // making a frame. Usually this means that user input for the frame is complete.
277 // If the scheduler is busy, we queue the BeginFrame to be handled later as 270 // If the scheduler is busy, we queue the BeginFrame to be handled later as
278 // a BeginRetroFrame. 271 // a BeginRetroFrame.
279 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 272 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
280 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 273 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
281 274
275 if (!state_machine_.BeginFrameNeeded()) {
brianderson 2016/09/19 22:56:44 This block of code may cause us to skip frames in
sunnyps 2016/09/19 23:59:04 This is handled by missed begin frames which are s
276 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
277 TRACE_EVENT_SCOPE_THREAD);
278 return false;
279 }
280
282 // Trace this begin frame time through the Chrome stack 281 // Trace this begin frame time through the Chrome stack
283 TRACE_EVENT_FLOW_BEGIN0( 282 TRACE_EVENT_FLOW_BEGIN0(
284 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 283 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
285 args.frame_time.ToInternalValue()); 284 args.frame_time.ToInternalValue());
286 285
287 // TODO(brianderson): Adjust deadline in the DisplayScheduler. 286 // TODO(brianderson): Adjust deadline in the DisplayScheduler.
288 BeginFrameArgs adjusted_args(args); 287 BeginFrameArgs adjusted_args(args);
289 adjusted_args.deadline -= EstimatedParentDrawTime(); 288 adjusted_args.deadline -= EstimatedParentDrawTime();
290 289
291 if (settings_.using_synchronous_renderer_compositor) { 290 if (settings_.using_synchronous_renderer_compositor) {
292 BeginImplFrameSynchronous(adjusted_args); 291 BeginImplFrameSynchronous(adjusted_args);
293 return true; 292 return true;
294 } 293 }
295 294
296 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has 295 if (inside_process_scheduled_actions_) {
297 // sent us the last BeginFrame we have missed. As we might not be able to 296 // The BFS can send a missed begin frame inside AddObserver. We can't handle
298 // actually make rendering for this call, handle it like a "retro frame". 297 // a begin frame inside ProcessScheduledActions so post a task.
299 // TODO(brainderson): Add a test for this functionality ASAP! 298 DCHECK_EQ(adjusted_args.type, BeginFrameArgs::MISSED);
300 if (adjusted_args.type == BeginFrameArgs::MISSED) { 299 DCHECK(missed_begin_frame_task_.IsCancelled());
301 begin_retro_frame_args_.push_back(adjusted_args); 300 missed_begin_frame_task_.Reset(
302 PostBeginRetroFrameIfNeeded(); 301 base::Bind(&Scheduler::BeginImplFrameWithDeadline,
302 base::Unretained(this), adjusted_args));
303 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
303 return true; 304 return true;
304 } 305 }
305 306
306 bool should_defer_begin_frame = 307 BeginImplFrameWithDeadline(adjusted_args);
307 !begin_retro_frame_args_.empty() ||
308 !begin_retro_frame_task_.IsCancelled() ||
309 !observing_begin_frame_source_ ||
310 (state_machine_.begin_impl_frame_state() !=
311 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
312
313 if (should_defer_begin_frame) {
314 begin_retro_frame_args_.push_back(adjusted_args);
315 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred",
316 TRACE_EVENT_SCOPE_THREAD);
317 // Queuing the frame counts as "using it", so we need to return true.
318 } else {
319 BeginImplFrameWithDeadline(adjusted_args);
320 }
321 return true; 308 return true;
322 } 309 }
323 310
324 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { 311 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
325 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); 312 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
326 ProcessScheduledActions(); 313 ProcessScheduledActions();
327 } 314 }
328 315
329 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { 316 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) {
330 DCHECK(settings_.using_synchronous_renderer_compositor); 317 DCHECK(settings_.using_synchronous_renderer_compositor);
331 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 318 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
332 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 319 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
333 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 320 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
334 321
335 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); 322 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw);
336 state_machine_.OnBeginImplFrameDeadline(); 323 state_machine_.OnBeginImplFrameDeadline();
337 ProcessScheduledActions(); 324 ProcessScheduledActions();
338 325
339 state_machine_.OnBeginImplFrameIdle(); 326 state_machine_.OnBeginImplFrameIdle();
340 ProcessScheduledActions(); 327 ProcessScheduledActions();
341 state_machine_.SetResourcelessSoftwareDraw(false); 328 state_machine_.SetResourcelessSoftwareDraw(false);
342 } 329 }
343 330
344 // BeginRetroFrame is called for BeginFrames that we've deferred because 331 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
345 // the scheduler was in the middle of processing a previous BeginFrame. 332 // The storage for |args| is owned by the missed begin frame task. Therefore
346 void Scheduler::BeginRetroFrame() { 333 // save |args| before cancelling the task either here or in the deadline.
347 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); 334 BeginFrameArgs adjusted_args = args;
348 DCHECK(!settings_.using_synchronous_renderer_compositor); 335 // Cancel the missed begin frame task in case the BFS sends a begin frame
349 DCHECK(!begin_retro_frame_args_.empty()); 336 // before the missed frame task runs.
350 DCHECK(!begin_retro_frame_task_.IsCancelled()); 337 missed_begin_frame_task_.Cancel();
338
339 // Discard missed begin frames in renderer scheduler if they are too late.
brianderson 2016/09/19 22:56:44 Can you add a comment explaining why there's a dif
sunnyps 2016/09/19 23:59:04 Actually I removed the exception for the browser.
340 if (!settings_.commit_to_active_tree &&
341 adjusted_args.type == BeginFrameArgs::MISSED &&
342 Now() > adjusted_args.deadline) {
343 begin_frame_source_->DidFinishFrame(this, 0);
344 return;
345 }
346
347 // Run the previous deadline if any.
348 if (state_machine_.begin_impl_frame_state() ==
349 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
350 OnBeginImplFrameDeadline();
351 // We may not need begin frames any longer.
352 if (!observing_begin_frame_source_) {
353 begin_frame_source_->DidFinishFrame(this, 0);
354 return;
355 }
356 }
351 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 357 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
352 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 358 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
353 359
354 begin_retro_frame_task_.Cancel();
355
356 // Discard expired BeginRetroFrames
357 // Today, we should always end up with at most one un-expired BeginRetroFrame
358 // because deadlines will not be greater than the next frame time. We don't
359 // DCHECK though because some systems don't always have monotonic timestamps.
360 // TODO(brianderson): In the future, long deadlines could result in us not
361 // draining the queue if we don't catch up. If we consistently can't catch
362 // up, our fallback should be to lower our frame rate.
363 base::TimeTicks now = Now();
364
365 while (!begin_retro_frame_args_.empty()) {
366 const BeginFrameArgs& args = begin_retro_frame_args_.front();
367 base::TimeTicks expiration_time = args.deadline;
368 if (now <= expiration_time)
369 break;
370 TRACE_EVENT_INSTANT2(
371 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD,
372 "expiration_time - now", (expiration_time - now).InMillisecondsF(),
373 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
374 begin_retro_frame_args_.pop_front();
375 if (begin_frame_source_)
376 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
377 }
378
379 if (begin_retro_frame_args_.empty()) {
380 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired",
381 TRACE_EVENT_SCOPE_THREAD);
382 } else {
383 BeginFrameArgs front = begin_retro_frame_args_.front();
384 begin_retro_frame_args_.pop_front();
385 BeginImplFrameWithDeadline(front);
386 }
387 }
388
389 // There could be a race between the posted BeginRetroFrame and a new
390 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
391 // will check if there is a pending BeginRetroFrame to ensure we handle
392 // BeginFrames in FIFO order.
393 void Scheduler::PostBeginRetroFrameIfNeeded() {
394 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
395 "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue());
396 if (!observing_begin_frame_source_)
397 return;
398
399 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
400 return;
401
402 // begin_retro_frame_args_ should always be empty for the
403 // synchronous compositor.
404 DCHECK(!settings_.using_synchronous_renderer_compositor);
405
406 if (state_machine_.begin_impl_frame_state() !=
407 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
408 return;
409
410 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
411
412 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
413 }
414
415 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
416 bool main_thread_is_in_high_latency_mode = 360 bool main_thread_is_in_high_latency_mode =
417 state_machine_.main_thread_missed_last_deadline(); 361 state_machine_.main_thread_missed_last_deadline();
418 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 362 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
419 args.AsValue(), "main_thread_missed_last_deadline", 363 adjusted_args.AsValue(), "main_thread_missed_last_deadline",
420 main_thread_is_in_high_latency_mode); 364 main_thread_is_in_high_latency_mode);
421 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 365 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
422 "MainThreadLatency", main_thread_is_in_high_latency_mode); 366 "MainThreadLatency", main_thread_is_in_high_latency_mode);
423 367
424 BeginFrameArgs adjusted_args = args; 368 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
369 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
370
425 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); 371 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
426 adjusted_args.deadline -= kDeadlineFudgeFactor; 372 adjusted_args.deadline -= kDeadlineFudgeFactor;
427 373
428 base::TimeDelta bmf_start_to_activate = 374 base::TimeDelta bmf_start_to_activate =
429 compositor_timing_history_ 375 compositor_timing_history_
430 ->BeginMainFrameStartToCommitDurationEstimate() + 376 ->BeginMainFrameStartToCommitDurationEstimate() +
431 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + 377 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
432 compositor_timing_history_->ActivateDurationEstimate(); 378 compositor_timing_history_->ActivateDurationEstimate();
433 379
434 base::TimeDelta bmf_to_activate_estimate_critical = 380 base::TimeDelta bmf_to_activate_estimate_critical =
435 bmf_start_to_activate + 381 bmf_start_to_activate +
436 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); 382 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate();
437 383
438 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( 384 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(
439 bmf_to_activate_estimate_critical < args.interval); 385 bmf_to_activate_estimate_critical < adjusted_args.interval);
440 386
441 // Update the BeginMainFrame args now that we know whether the main 387 // Update the BeginMainFrame args now that we know whether the main
442 // thread will be on the critical path or not. 388 // thread will be on the critical path or not.
443 begin_main_frame_args_ = adjusted_args; 389 begin_main_frame_args_ = adjusted_args;
444 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 390 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
445 391
446 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; 392 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical;
447 if (!begin_main_frame_args_.on_critical_path) { 393 if (!begin_main_frame_args_.on_critical_path) {
448 bmf_to_activate_estimate = 394 bmf_to_activate_estimate =
449 bmf_start_to_activate + 395 bmf_start_to_activate +
450 compositor_timing_history_ 396 compositor_timing_history_
451 ->BeginMainFrameQueueDurationNotCriticalEstimate(); 397 ->BeginMainFrameQueueDurationNotCriticalEstimate();
452 } 398 }
453 399
454 bool can_activate_before_deadline = 400 bool can_activate_before_deadline =
455 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, 401 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args,
456 bmf_to_activate_estimate); 402 bmf_to_activate_estimate);
457 403
458 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 404 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
459 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 405 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
460 TRACE_EVENT_SCOPE_THREAD); 406 TRACE_EVENT_SCOPE_THREAD);
461 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 407 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
462 } else if (ShouldRecoverImplLatency(adjusted_args, 408 } else if (ShouldRecoverImplLatency(adjusted_args,
463 can_activate_before_deadline)) { 409 can_activate_before_deadline)) {
464 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 410 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
465 TRACE_EVENT_SCOPE_THREAD); 411 TRACE_EVENT_SCOPE_THREAD);
466 if (begin_frame_source_) 412 if (begin_frame_source_)
467 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); 413 begin_frame_source_->DidFinishFrame(this, 0);
468 return; 414 return;
469 } 415 }
470 416
471 BeginImplFrame(adjusted_args); 417 BeginImplFrame(adjusted_args);
472 } 418 }
473 419
474 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 420 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
475 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 421 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
476 args.AsValue()); 422 args.AsValue());
477 423
478 // The main thread currently can't commit before we draw with the 424 // The main thread currently can't commit before we draw with the
479 // synchronous compositor, so never consider the BeginMainFrame fast. 425 // synchronous compositor, so never consider the BeginMainFrame fast.
480 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 426 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
481 begin_main_frame_args_ = args; 427 begin_main_frame_args_ = args;
482 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 428 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
483 429
484 BeginImplFrame(args); 430 BeginImplFrame(args);
485 compositor_timing_history_->WillFinishImplFrame( 431 compositor_timing_history_->WillFinishImplFrame(
486 state_machine_.needs_redraw()); 432 state_machine_.needs_redraw());
487 FinishImplFrame(); 433 FinishImplFrame();
488 } 434 }
489 435
490 void Scheduler::FinishImplFrame() { 436 void Scheduler::FinishImplFrame() {
491 state_machine_.OnBeginImplFrameIdle(); 437 state_machine_.OnBeginImplFrameIdle();
492 ProcessScheduledActions(); 438 ProcessScheduledActions();
493 439
494 client_->DidFinishImplFrame(); 440 client_->DidFinishImplFrame();
495 if (begin_frame_source_) 441 if (begin_frame_source_)
496 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); 442 begin_frame_source_->DidFinishFrame(this, 0);
497 begin_impl_frame_tracker_.Finish(); 443 begin_impl_frame_tracker_.Finish();
498 } 444 }
499 445
500 // BeginImplFrame starts a compositor frame that will wait up until a deadline 446 // BeginImplFrame starts a compositor frame that will wait up until a deadline
501 // for a BeginMainFrame+activation to complete before it times out and draws 447 // for a BeginMainFrame+activation to complete before it times out and draws
502 // any asynchronous animation and scroll/pinch updates. 448 // any asynchronous animation and scroll/pinch updates.
503 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 449 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
504 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 450 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
505 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 451 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
506 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 452 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 state_machine_.AsValueInto(state.get()); 661 state_machine_.AsValueInto(state.get());
716 state->EndDictionary(); 662 state->EndDictionary();
717 663
718 state->BeginDictionary("scheduler_state"); 664 state->BeginDictionary("scheduler_state");
719 state->SetBoolean("throttle_frame_production_", 665 state->SetBoolean("throttle_frame_production_",
720 settings_.throttle_frame_production); 666 settings_.throttle_frame_production);
721 state->SetDouble("estimated_parent_draw_time_ms", 667 state->SetDouble("estimated_parent_draw_time_ms",
722 estimated_parent_draw_time_.InMillisecondsF()); 668 estimated_parent_draw_time_.InMillisecondsF());
723 state->SetBoolean("observing_begin_frame_source", 669 state->SetBoolean("observing_begin_frame_source",
724 observing_begin_frame_source_); 670 observing_begin_frame_source_);
725 state->SetInteger("begin_retro_frame_args",
726 static_cast<int>(begin_retro_frame_args_.size()));
727 state->SetBoolean("begin_retro_frame_task",
728 !begin_retro_frame_task_.IsCancelled());
729 state->SetBoolean("begin_impl_frame_deadline_task", 671 state->SetBoolean("begin_impl_frame_deadline_task",
730 !begin_impl_frame_deadline_task_.IsCancelled()); 672 !begin_impl_frame_deadline_task_.IsCancelled());
673 state->SetBoolean("missed_begin_frame_task",
674 !missed_begin_frame_task_.IsCancelled());
731 state->SetString("inside_action", 675 state->SetString("inside_action",
732 SchedulerStateMachine::ActionToString(inside_action_)); 676 SchedulerStateMachine::ActionToString(inside_action_));
733 677
734 state->BeginDictionary("begin_impl_frame_args"); 678 state->BeginDictionary("begin_impl_frame_args");
735 begin_impl_frame_tracker_.AsValueInto(now, state.get()); 679 begin_impl_frame_tracker_.AsValueInto(now, state.get());
736 state->EndDictionary(); 680 state->EndDictionary();
737 681
738 state->SetString("begin_impl_frame_deadline_mode_", 682 state->SetString("begin_impl_frame_deadline_mode_",
739 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( 683 SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
740 begin_impl_frame_deadline_mode_)); 684 begin_impl_frame_deadline_mode_));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 } 762 }
819 763
820 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 764 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
821 return (state_machine_.begin_main_frame_state() == 765 return (state_machine_.begin_main_frame_state() ==
822 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 766 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
823 state_machine_.begin_main_frame_state() == 767 state_machine_.begin_main_frame_state() ==
824 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 768 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
825 } 769 }
826 770
827 } // namespace cc 771 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698