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

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

Issue 2753843003: Create a new action triggered when a BeginMainFrame is not expected before vsync (Closed)
Patch Set: missed one Created 3 years, 9 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_state_machine.h" 5 #include "cc/scheduler/scheduler_state_machine.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 24 matching lines...) Expand all
35 BeginFrameArgs::kInvalidFrameNumber), 35 BeginFrameArgs::kInvalidFrameNumber),
36 last_begin_frame_sequence_number_compositor_frame_was_fresh_( 36 last_begin_frame_sequence_number_compositor_frame_was_fresh_(
37 BeginFrameArgs::kInvalidFrameNumber), 37 BeginFrameArgs::kInvalidFrameNumber),
38 commit_count_(0), 38 commit_count_(0),
39 current_frame_number_(0), 39 current_frame_number_(0),
40 last_frame_number_submit_performed_(-1), 40 last_frame_number_submit_performed_(-1),
41 last_frame_number_draw_performed_(-1), 41 last_frame_number_draw_performed_(-1),
42 last_frame_number_begin_main_frame_sent_(-1), 42 last_frame_number_begin_main_frame_sent_(-1),
43 last_frame_number_invalidate_compositor_frame_sink_performed_(-1), 43 last_frame_number_invalidate_compositor_frame_sink_performed_(-1),
44 draw_funnel_(false), 44 draw_funnel_(false),
45 send_begin_main_frame_funnel_(true), 45 did_send_begin_main_frame_for_current_frame_(true),
46 invalidate_compositor_frame_sink_funnel_(false), 46 invalidate_compositor_frame_sink_funnel_(false),
47 impl_side_invalidation_funnel_(false), 47 impl_side_invalidation_funnel_(false),
48 did_do_idle_work_(false),
48 prepare_tiles_funnel_(0), 49 prepare_tiles_funnel_(0),
49 consecutive_checkerboard_animations_(0), 50 consecutive_checkerboard_animations_(0),
50 pending_submit_frames_(0), 51 pending_submit_frames_(0),
51 submit_frames_with_current_compositor_frame_sink_(0), 52 submit_frames_with_current_compositor_frame_sink_(0),
52 needs_redraw_(false), 53 needs_redraw_(false),
53 needs_prepare_tiles_(false), 54 needs_prepare_tiles_(false),
54 needs_begin_main_frame_(false), 55 needs_begin_main_frame_(false),
55 needs_one_begin_impl_frame_(false), 56 needs_one_begin_impl_frame_(false),
56 visible_(false), 57 visible_(false),
57 begin_frame_source_paused_(false), 58 begin_frame_source_paused_(false),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 case ACTION_DRAW_ABORT: 188 case ACTION_DRAW_ABORT:
188 return "ACTION_DRAW_ABORT"; 189 return "ACTION_DRAW_ABORT";
189 case ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION: 190 case ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION:
190 return "ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION"; 191 return "ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION";
191 case ACTION_PREPARE_TILES: 192 case ACTION_PREPARE_TILES:
192 return "ACTION_PREPARE_TILES"; 193 return "ACTION_PREPARE_TILES";
193 case ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK: 194 case ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK:
194 return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK"; 195 return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK";
195 case ACTION_PERFORM_IMPL_SIDE_INVALIDATION: 196 case ACTION_PERFORM_IMPL_SIDE_INVALIDATION:
196 return "ACTION_PERFORM_IMPL_SIDE_INVALIDATION"; 197 return "ACTION_PERFORM_IMPL_SIDE_INVALIDATION";
198 case ACTION_DO_SHORT_IDLE_WORK:
199 return "ACTION_DO_SHORT_IDLE_WORK";
197 } 200 }
198 NOTREACHED(); 201 NOTREACHED();
199 return "???"; 202 return "???";
200 } 203 }
201 204
202 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 205 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
203 SchedulerStateMachine::AsValue() const { 206 SchedulerStateMachine::AsValue() const {
204 std::unique_ptr<base::trace_event::TracedValue> state( 207 std::unique_ptr<base::trace_event::TracedValue> state(
205 new base::trace_event::TracedValue()); 208 new base::trace_event::TracedValue());
206 AsValueInto(state.get()); 209 AsValueInto(state.get());
(...skipping 30 matching lines...) Expand all
237 state->SetInteger("last_begin_frame_sequence_number_begin_main_frame_sent", 240 state->SetInteger("last_begin_frame_sequence_number_begin_main_frame_sent",
238 last_begin_frame_sequence_number_begin_main_frame_sent_); 241 last_begin_frame_sequence_number_begin_main_frame_sent_);
239 state->SetInteger("last_begin_frame_sequence_number_pending_tree_was_fresh", 242 state->SetInteger("last_begin_frame_sequence_number_pending_tree_was_fresh",
240 last_begin_frame_sequence_number_pending_tree_was_fresh_); 243 last_begin_frame_sequence_number_pending_tree_was_fresh_);
241 state->SetInteger("last_begin_frame_sequence_number_active_tree_was_fresh", 244 state->SetInteger("last_begin_frame_sequence_number_active_tree_was_fresh",
242 last_begin_frame_sequence_number_active_tree_was_fresh_); 245 last_begin_frame_sequence_number_active_tree_was_fresh_);
243 state->SetInteger( 246 state->SetInteger(
244 "last_begin_frame_sequence_number_compositor_frame_was_fresh", 247 "last_begin_frame_sequence_number_compositor_frame_was_fresh",
245 last_begin_frame_sequence_number_compositor_frame_was_fresh_); 248 last_begin_frame_sequence_number_compositor_frame_was_fresh_);
246 state->SetBoolean("funnel: draw_funnel", draw_funnel_); 249 state->SetBoolean("funnel: draw_funnel", draw_funnel_);
247 state->SetBoolean("funnel: send_begin_main_frame_funnel", 250 state->SetBoolean("funnel: did_send_begin_main_frame",
248 send_begin_main_frame_funnel_); 251 did_send_begin_main_frame_for_current_frame_);
252 state->SetBoolean("funnel: did_do_idle_work", did_do_idle_work_);
249 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); 253 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
250 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel", 254 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel",
251 invalidate_compositor_frame_sink_funnel_); 255 invalidate_compositor_frame_sink_funnel_);
252 state->SetBoolean("funnel: impl_side_invalidation_funnel", 256 state->SetBoolean("funnel: impl_side_invalidation_funnel",
253 impl_side_invalidation_funnel_); 257 impl_side_invalidation_funnel_);
254 state->SetInteger("consecutive_checkerboard_animations", 258 state->SetInteger("consecutive_checkerboard_animations",
255 consecutive_checkerboard_animations_); 259 consecutive_checkerboard_animations_);
256 state->SetInteger("pending_submit_frames_", pending_submit_frames_); 260 state->SetInteger("pending_submit_frames_", pending_submit_frames_);
257 state->SetInteger("submit_frames_with_current_compositor_frame_sink", 261 state->SetInteger("submit_frames_with_current_compositor_frame_sink",
258 submit_frames_with_current_compositor_frame_sink_); 262 submit_frames_with_current_compositor_frame_sink_);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 return false; 425 return false;
422 426
423 // If we want to force activation, do so ASAP. 427 // If we want to force activation, do so ASAP.
424 if (PendingActivationsShouldBeForced()) 428 if (PendingActivationsShouldBeForced())
425 return true; 429 return true;
426 430
427 // At this point, only activate if we are ready to activate. 431 // At this point, only activate if we are ready to activate.
428 return pending_tree_is_ready_for_activation_; 432 return pending_tree_is_ready_for_activation_;
429 } 433 }
430 434
435 bool SchedulerStateMachine::ShouldDoShortIdleWork() const {
436 // BeginMainFrame already triggers idle work, so we don't need to schedule
437 // extra idle work here.
438 if (needs_begin_main_frame_ || did_send_begin_main_frame_for_current_frame_)
439 return false;
440
441 // Only schedule extra idle work when we're visible.
442 if (!visible_)
443 return false;
444
445 // There are no BeginImplFrames while BeginFrameSource is paused,
446 // so should also stop scheduling extra idle work.
447 if (begin_frame_source_paused_)
448 return false;
449
450 // Do not do idle work too many times in a single frame or before
451 // the first BeginFrame.
452 if (did_do_idle_work_)
453 return false;
454
455 // If a BeginMainFrame is in progress, don't do any extra idle work.
456 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
457 return false;
458
459 return true;
460 }
461
431 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { 462 bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
432 if (!needs_begin_main_frame_) 463 if (!needs_begin_main_frame_)
433 return false; 464 return false;
434 465
435 // We can not perform commits if we are not visible. 466 // We can not perform commits if we are not visible.
436 if (!visible_) 467 if (!visible_)
437 return false; 468 return false;
438 469
439 // There are no BeginImplFrames while BeginFrameSource is paused, 470 // There are no BeginImplFrames while BeginFrameSource is paused,
440 // so should also stop BeginMainFrames. 471 // so should also stop BeginMainFrames.
441 if (begin_frame_source_paused_) 472 if (begin_frame_source_paused_)
442 return false; 473 return false;
443 474
444 // Do not make a new commits when it is deferred. 475 // Do not make a new commits when it is deferred.
445 if (defer_commits_) 476 if (defer_commits_)
446 return false; 477 return false;
447 478
448 return true; 479 return true;
449 } 480 }
450 481
451 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { 482 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
452 if (!CouldSendBeginMainFrame()) 483 if (!CouldSendBeginMainFrame())
453 return false; 484 return false;
454 485
455 // Do not send begin main frame too many times in a single frame or before 486 // Do not send begin main frame too many times in a single frame or before
456 // the first BeginFrame. 487 // the first BeginFrame.
457 if (send_begin_main_frame_funnel_) 488 if (did_send_begin_main_frame_for_current_frame_)
458 return false; 489 return false;
459 490
460 // Only send BeginMainFrame when there isn't another commit pending already. 491 // Only send BeginMainFrame when there isn't another commit pending already.
461 // Other parts of the state machine indirectly defer the BeginMainFrame 492 // Other parts of the state machine indirectly defer the BeginMainFrame
462 // by transitioning to WAITING commit states rather than going 493 // by transitioning to WAITING commit states rather than going
463 // immediately to IDLE. 494 // immediately to IDLE.
464 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) 495 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
465 return false; 496 return false;
466 497
467 // MFBA is disabled and we are waiting for previous activation. 498 // MFBA is disabled and we are waiting for previous activation.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 if (ShouldPerformImplSideInvalidation()) 622 if (ShouldPerformImplSideInvalidation())
592 return ACTION_PERFORM_IMPL_SIDE_INVALIDATION; 623 return ACTION_PERFORM_IMPL_SIDE_INVALIDATION;
593 if (ShouldPrepareTiles()) 624 if (ShouldPrepareTiles())
594 return ACTION_PREPARE_TILES; 625 return ACTION_PREPARE_TILES;
595 if (ShouldSendBeginMainFrame()) 626 if (ShouldSendBeginMainFrame())
596 return ACTION_SEND_BEGIN_MAIN_FRAME; 627 return ACTION_SEND_BEGIN_MAIN_FRAME;
597 if (ShouldInvalidateCompositorFrameSink()) 628 if (ShouldInvalidateCompositorFrameSink())
598 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK; 629 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK;
599 if (ShouldBeginCompositorFrameSinkCreation()) 630 if (ShouldBeginCompositorFrameSinkCreation())
600 return ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION; 631 return ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION;
632 if (ShouldDoShortIdleWork())
633 return ACTION_DO_SHORT_IDLE_WORK;
601 return ACTION_NONE; 634 return ACTION_NONE;
602 } 635 }
603 636
604 bool SchedulerStateMachine::ShouldPerformImplSideInvalidation() const { 637 bool SchedulerStateMachine::ShouldPerformImplSideInvalidation() const {
605 if (!needs_impl_side_invalidation_) 638 if (!needs_impl_side_invalidation_)
606 return false; 639 return false;
607 640
608 if (!CouldCreatePendingTree()) 641 if (!CouldCreatePendingTree())
609 return false; 642 return false;
610 643
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 if (!HasInitializedCompositorFrameSink()) 709 if (!HasInitializedCompositorFrameSink())
677 return false; 710 return false;
678 711
679 return true; 712 return true;
680 } 713 }
681 714
682 void SchedulerStateMachine::WillSendBeginMainFrame() { 715 void SchedulerStateMachine::WillSendBeginMainFrame() {
683 DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled); 716 DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled);
684 DCHECK(visible_); 717 DCHECK(visible_);
685 DCHECK(!begin_frame_source_paused_); 718 DCHECK(!begin_frame_source_paused_);
686 DCHECK(!send_begin_main_frame_funnel_); 719 DCHECK(!did_send_begin_main_frame_for_current_frame_);
687 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_SENT; 720 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_SENT;
688 needs_begin_main_frame_ = false; 721 needs_begin_main_frame_ = false;
689 send_begin_main_frame_funnel_ = true; 722 did_send_begin_main_frame_for_current_frame_ = true;
690 last_frame_number_begin_main_frame_sent_ = current_frame_number_; 723 last_frame_number_begin_main_frame_sent_ = current_frame_number_;
691 last_begin_frame_sequence_number_begin_main_frame_sent_ = 724 last_begin_frame_sequence_number_begin_main_frame_sent_ =
692 begin_frame_sequence_number_; 725 begin_frame_sequence_number_;
693 } 726 }
694 727
728 void SchedulerStateMachine::WillDoShortIdleWork() {
729 DCHECK(visible_);
730 DCHECK(!begin_frame_source_paused_);
731 DCHECK(!did_do_idle_work_);
732 did_do_idle_work_ = true;
733 }
734
695 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { 735 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
696 bool can_have_pending_tree = 736 bool can_have_pending_tree =
697 commit_has_no_updates && 737 commit_has_no_updates &&
698 (settings_.main_frame_before_activation_enabled || 738 (settings_.main_frame_before_activation_enabled ||
699 current_pending_tree_is_impl_side_); 739 current_pending_tree_is_impl_side_);
700 DCHECK(!has_pending_tree_ || can_have_pending_tree); 740 DCHECK(!has_pending_tree_ || can_have_pending_tree);
701 commit_count_++; 741 commit_count_++;
702 last_commit_had_no_updates_ = commit_has_no_updates; 742 last_commit_had_no_updates_ = commit_has_no_updates;
703 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; 743 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE;
704 744
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 1080
1041 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 1081 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
1042 current_frame_number_++; 1082 current_frame_number_++;
1043 1083
1044 last_commit_had_no_updates_ = false; 1084 last_commit_had_no_updates_ = false;
1045 did_draw_in_last_frame_ = false; 1085 did_draw_in_last_frame_ = false;
1046 did_submit_in_last_frame_ = false; 1086 did_submit_in_last_frame_ = false;
1047 needs_one_begin_impl_frame_ = false; 1087 needs_one_begin_impl_frame_ = false;
1048 1088
1049 // Clear funnels for any actions we perform during the frame. 1089 // Clear funnels for any actions we perform during the frame.
1050 send_begin_main_frame_funnel_ = false; 1090 did_do_idle_work_ = false;
1091 did_send_begin_main_frame_for_current_frame_ = false;
1051 invalidate_compositor_frame_sink_funnel_ = false; 1092 invalidate_compositor_frame_sink_funnel_ = false;
1052 impl_side_invalidation_funnel_ = false; 1093 impl_side_invalidation_funnel_ = false;
1053 1094
1054 // "Drain" the PrepareTiles funnel. 1095 // "Drain" the PrepareTiles funnel.
1055 if (prepare_tiles_funnel_ > 0) 1096 if (prepare_tiles_funnel_ > 0)
1056 prepare_tiles_funnel_--; 1097 prepare_tiles_funnel_--;
1057 } 1098 }
1058 1099
1059 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 1100 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
1060 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 1101 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
(...skipping 17 matching lines...) Expand all
1078 skip_next_begin_main_frame_to_reduce_latency_ = false; 1119 skip_next_begin_main_frame_to_reduce_latency_ = false;
1079 1120
1080 // If a new or undrawn active tree is pending after the deadline, 1121 // If a new or undrawn active tree is pending after the deadline,
1081 // then the main thread is in a high latency mode. 1122 // then the main thread is in a high latency mode.
1082 main_thread_missed_last_deadline_ = 1123 main_thread_missed_last_deadline_ =
1083 CommitPending() || has_pending_tree_ || active_tree_needs_first_draw_; 1124 CommitPending() || has_pending_tree_ || active_tree_needs_first_draw_;
1084 1125
1085 // If we're entering a state where we won't get BeginFrames set all the 1126 // If we're entering a state where we won't get BeginFrames set all the
1086 // funnels so that we don't perform any actions that we shouldn't. 1127 // funnels so that we don't perform any actions that we shouldn't.
1087 if (!BeginFrameNeeded()) 1128 if (!BeginFrameNeeded())
1088 send_begin_main_frame_funnel_ = true; 1129 did_send_begin_main_frame_for_current_frame_ = true;
1089 1130
1090 // Synchronous compositor finishes BeginFrames before triggering their 1131 // Synchronous compositor finishes BeginFrames before triggering their
1091 // deadline. Therefore, we update sequence numbers when becoming idle, before 1132 // deadline. Therefore, we update sequence numbers when becoming idle, before
1092 // the Scheduler sends its BeginFrameAck. 1133 // the Scheduler sends its BeginFrameAck.
1093 if (settings_.using_synchronous_renderer_compositor) 1134 if (settings_.using_synchronous_renderer_compositor)
1094 UpdateBeginFrameSequenceNumbersForBeginFrameDeadline(); 1135 UpdateBeginFrameSequenceNumbersForBeginFrameDeadline();
1095 } 1136 }
1096 1137
1097 SchedulerStateMachine::BeginImplFrameDeadlineMode 1138 SchedulerStateMachine::BeginImplFrameDeadlineMode
1098 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 1139 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 case COMPOSITOR_FRAME_SINK_ACTIVE: 1376 case COMPOSITOR_FRAME_SINK_ACTIVE:
1336 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: 1377 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT:
1337 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: 1378 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION:
1338 return true; 1379 return true;
1339 } 1380 }
1340 NOTREACHED(); 1381 NOTREACHED();
1341 return false; 1382 return false;
1342 } 1383 }
1343 1384
1344 } // namespace cc 1385 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698