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

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

Issue 2632563003: [cc] Calculate the correct latest_confirmed_sequence_number in cc::Scheduler. (Closed)
Patch Set: handle BeginFrameDropped and add test for it. Created 3 years, 10 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 // BeginFrame is the mechanism that tells us that now is a good time to start 254 // BeginFrame is the mechanism that tells us that now is a good time to start
255 // making a frame. Usually this means that user input for the frame is complete. 255 // making a frame. Usually this means that user input for the frame is complete.
256 // If the scheduler is busy, we queue the BeginFrame to be handled later as 256 // If the scheduler is busy, we queue the BeginFrame to be handled later as
257 // a BeginRetroFrame. 257 // a BeginRetroFrame.
258 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 258 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
259 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 259 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
260 260
261 if (!state_machine_.BeginFrameNeeded()) { 261 if (!state_machine_.BeginFrameNeeded()) {
262 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", 262 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
263 TRACE_EVENT_SCOPE_THREAD); 263 TRACE_EVENT_SCOPE_THREAD);
264 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 264 // Since we don't use the BeginFrame, we may later receive the same
265 BeginFrameAck ack(args.source_id, args.sequence_number, 265 // BeginFrame again. Thus, we can't confirm it at this point, even though we
266 args.sequence_number, 0, false); 266 // don't have any updates right now.
267 begin_frame_source_->DidFinishFrame(this, ack); 267 SendBeginFrameAck(args, kBeginFrameSkipped);
Eric Seckler 2017/02/23 12:58:00 Since we require an ack here now, I've added a com
268 return false; 268 return false;
269 } 269 }
270 270
271 // Trace this begin frame time through the Chrome stack 271 // Trace this begin frame time through the Chrome stack
272 TRACE_EVENT_FLOW_BEGIN0( 272 TRACE_EVENT_FLOW_BEGIN0(
273 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 273 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
274 args.frame_time.ToInternalValue()); 274 args.frame_time.ToInternalValue());
275 275
276 if (settings_.using_synchronous_renderer_compositor) { 276 if (settings_.using_synchronous_renderer_compositor) {
277 BeginImplFrameSynchronous(args); 277 BeginImplFrameSynchronous(args);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 BeginFrameArgs adjusted_args = args; 319 BeginFrameArgs adjusted_args = args;
320 // Cancel the missed begin frame task in case the BFS sends a begin frame 320 // Cancel the missed begin frame task in case the BFS sends a begin frame
321 // before the missed frame task runs. 321 // before the missed frame task runs.
322 missed_begin_frame_task_.Cancel(); 322 missed_begin_frame_task_.Cancel();
323 323
324 base::TimeTicks now = Now(); 324 base::TimeTicks now = Now();
325 325
326 // Discard missed begin frames if they are too late. 326 // Discard missed begin frames if they are too late.
327 if (adjusted_args.type == BeginFrameArgs::MISSED && 327 if (adjusted_args.type == BeginFrameArgs::MISSED &&
328 now > adjusted_args.deadline) { 328 now > adjusted_args.deadline) {
329 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 329 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
330 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number,
331 adjusted_args.sequence_number, 0, false);
332 begin_frame_source_->DidFinishFrame(this, ack);
333 return; 330 return;
334 } 331 }
335 332
336 // Run the previous deadline if any. 333 // Run the previous deadline if any.
337 if (state_machine_.begin_impl_frame_state() == 334 if (state_machine_.begin_impl_frame_state() ==
338 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { 335 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
339 OnBeginImplFrameDeadline(); 336 OnBeginImplFrameDeadline();
340 // We may not need begin frames any longer. 337 // We may not need begin frames any longer.
341 if (!observing_begin_frame_source_) { 338 if (!observing_begin_frame_source_) {
342 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 339 // We need to confirm the ignored BeginFrame, since we don't have updates.
343 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, 340 // To persist the confirmation for future BeginFrameAcks, we let the state
344 adjusted_args.sequence_number, 0, false); 341 // machine know about the BeginFrame.
345 begin_frame_source_->DidFinishFrame(this, ack); 342 state_machine_.OnBeginFrameDroppedNotObserving(args.source_id,
343 args.sequence_number);
344 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
346 return; 345 return;
347 } 346 }
348 } 347 }
349 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 348 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
350 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 349 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
351 350
352 bool main_thread_is_in_high_latency_mode = 351 bool main_thread_is_in_high_latency_mode =
353 state_machine_.main_thread_missed_last_deadline(); 352 state_machine_.main_thread_missed_last_deadline();
354 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 353 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
355 adjusted_args.AsValue(), "main_thread_missed_last_deadline", 354 adjusted_args.AsValue(), "main_thread_missed_last_deadline",
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 bmf_to_activate_estimate, now); 393 bmf_to_activate_estimate, now);
395 394
396 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 395 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
397 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 396 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
398 TRACE_EVENT_SCOPE_THREAD); 397 TRACE_EVENT_SCOPE_THREAD);
399 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 398 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
400 } else if (ShouldRecoverImplLatency(adjusted_args, 399 } else if (ShouldRecoverImplLatency(adjusted_args,
401 can_activate_before_deadline)) { 400 can_activate_before_deadline)) {
402 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 401 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
403 TRACE_EVENT_SCOPE_THREAD); 402 TRACE_EVENT_SCOPE_THREAD);
404 if (begin_frame_source_) { 403 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameSkipped);
405 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|.
406 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number,
407 adjusted_args.sequence_number, 0, false);
408 begin_frame_source_->DidFinishFrame(this, ack);
409 }
410 return; 404 return;
411 } 405 }
412 406
413 BeginImplFrame(adjusted_args); 407 BeginImplFrame(adjusted_args);
414 } 408 }
415 409
416 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 410 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
417 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 411 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
418 args.AsValue()); 412 args.AsValue());
419 413
420 // The main thread currently can't commit before we draw with the 414 // The main thread currently can't commit before we draw with the
421 // synchronous compositor, so never consider the BeginMainFrame fast. 415 // synchronous compositor, so never consider the BeginMainFrame fast.
422 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 416 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
423 begin_main_frame_args_ = args; 417 begin_main_frame_args_ = args;
424 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 418 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
425 419
426 BeginImplFrame(args); 420 BeginImplFrame(args);
427 compositor_timing_history_->WillFinishImplFrame( 421 compositor_timing_history_->WillFinishImplFrame(
428 state_machine_.needs_redraw()); 422 state_machine_.needs_redraw());
429 FinishImplFrame(); 423 FinishImplFrame();
430 } 424 }
431 425
432 void Scheduler::FinishImplFrame() { 426 void Scheduler::FinishImplFrame() {
433 state_machine_.OnBeginImplFrameIdle(); 427 state_machine_.OnBeginImplFrameIdle();
434 ProcessScheduledActions(); 428 ProcessScheduledActions();
435 429
436 client_->DidFinishImplFrame(); 430 client_->DidFinishImplFrame();
437 if (begin_frame_source_) { 431 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished);
438 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 432 begin_impl_frame_tracker_.Finish();
439 BeginFrameAck ack(begin_main_frame_args_.source_id, 433 }
440 begin_main_frame_args_.sequence_number, 434
441 begin_main_frame_args_.sequence_number, 0, 435 void Scheduler::SendBeginFrameAck(const BeginFrameArgs& args,
442 state_machine_.did_submit_in_last_frame()); 436 BeginFrameResult result) {
443 begin_frame_source_->DidFinishFrame(this, ack); 437 if (!begin_frame_source_)
438 return;
439
440 uint64_t latest_confirmed_sequence_number =
441 BeginFrameArgs::kInvalidFrameNumber;
442 if (args.source_id == state_machine_.begin_frame_source_id()) {
443 latest_confirmed_sequence_number =
444 state_machine_
445 .last_begin_frame_sequence_number_compositor_frame_was_fresh();
444 } 446 }
445 begin_impl_frame_tracker_.Finish(); 447
448 bool did_submit = false;
449 if (result == kBeginFrameFinished) {
450 did_submit = state_machine_.did_submit_in_last_frame();
451 }
452
453 BeginFrameAck ack(args.source_id, args.sequence_number,
454 latest_confirmed_sequence_number, 0, did_submit);
455 begin_frame_source_->DidFinishFrame(this, ack);
446 } 456 }
447 457
448 // BeginImplFrame starts a compositor frame that will wait up until a deadline 458 // BeginImplFrame starts a compositor frame that will wait up until a deadline
449 // for a BeginMainFrame+activation to complete before it times out and draws 459 // for a BeginMainFrame+activation to complete before it times out and draws
450 // any asynchronous animation and scroll/pinch updates. 460 // any asynchronous animation and scroll/pinch updates.
451 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 461 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
452 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 462 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
453 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 463 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
454 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 464 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
455 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); 465 DCHECK(state_machine_.HasInitializedCompositorFrameSink());
456 466
457 begin_impl_frame_tracker_.Start(args); 467 begin_impl_frame_tracker_.Start(args);
458 state_machine_.OnBeginImplFrame(); 468 state_machine_.OnBeginImplFrame(args.source_id, args.sequence_number);
459 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 469 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
460 compositor_timing_history_->WillBeginImplFrame( 470 compositor_timing_history_->WillBeginImplFrame(
461 state_machine_.NewActiveTreeLikely()); 471 state_machine_.NewActiveTreeLikely());
462 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); 472 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current());
463 473
464 ProcessScheduledActions(); 474 ProcessScheduledActions();
465 } 475 }
466 476
467 void Scheduler::ScheduleBeginImplFrameDeadline() { 477 void Scheduler::ScheduleBeginImplFrameDeadline() {
468 // The synchronous compositor does not post a deadline task. 478 // The synchronous compositor does not post a deadline task.
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 } 781 }
772 782
773 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 783 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
774 return (state_machine_.begin_main_frame_state() == 784 return (state_machine_.begin_main_frame_state() ==
775 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 785 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
776 state_machine_.begin_main_frame_state() == 786 state_machine_.begin_main_frame_state() ==
777 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 787 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
778 } 788 }
779 789
780 } // namespace cc 790 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698