OLD | NEW |
---|---|
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 15 matching lines...) Expand all Loading... | |
26 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 26 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
27 commit_count_(0), | 27 commit_count_(0), |
28 current_frame_number_(0), | 28 current_frame_number_(0), |
29 last_frame_number_submit_performed_(-1), | 29 last_frame_number_submit_performed_(-1), |
30 last_frame_number_draw_performed_(-1), | 30 last_frame_number_draw_performed_(-1), |
31 last_frame_number_begin_main_frame_sent_(-1), | 31 last_frame_number_begin_main_frame_sent_(-1), |
32 last_frame_number_invalidate_compositor_frame_sink_performed_(-1), | 32 last_frame_number_invalidate_compositor_frame_sink_performed_(-1), |
33 draw_funnel_(false), | 33 draw_funnel_(false), |
34 send_begin_main_frame_funnel_(true), | 34 send_begin_main_frame_funnel_(true), |
35 invalidate_compositor_frame_sink_funnel_(false), | 35 invalidate_compositor_frame_sink_funnel_(false), |
36 impl_side_invalidation_funnel_(false), | |
36 prepare_tiles_funnel_(0), | 37 prepare_tiles_funnel_(0), |
37 consecutive_checkerboard_animations_(0), | 38 consecutive_checkerboard_animations_(0), |
38 pending_submit_frames_(0), | 39 pending_submit_frames_(0), |
39 submit_frames_with_current_compositor_frame_sink_(0), | 40 submit_frames_with_current_compositor_frame_sink_(0), |
40 needs_redraw_(false), | 41 needs_redraw_(false), |
41 needs_prepare_tiles_(false), | 42 needs_prepare_tiles_(false), |
42 needs_begin_main_frame_(false), | 43 needs_begin_main_frame_(false), |
43 needs_one_begin_impl_frame_(false), | 44 needs_one_begin_impl_frame_(false), |
44 visible_(false), | 45 visible_(false), |
45 begin_frame_source_paused_(false), | 46 begin_frame_source_paused_(false), |
46 resourceless_draw_(false), | 47 resourceless_draw_(false), |
47 can_draw_(false), | 48 can_draw_(false), |
48 has_pending_tree_(false), | 49 has_pending_tree_(false), |
49 pending_tree_is_ready_for_activation_(false), | 50 pending_tree_is_ready_for_activation_(false), |
50 active_tree_needs_first_draw_(false), | 51 active_tree_needs_first_draw_(false), |
51 did_create_and_initialize_first_compositor_frame_sink_(false), | 52 did_create_and_initialize_first_compositor_frame_sink_(false), |
52 tree_priority_(NEW_CONTENT_TAKES_PRIORITY), | 53 tree_priority_(NEW_CONTENT_TAKES_PRIORITY), |
53 scroll_handler_state_( | 54 scroll_handler_state_( |
54 ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER), | 55 ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER), |
55 critical_begin_main_frame_to_activate_is_fast_(true), | 56 critical_begin_main_frame_to_activate_is_fast_(true), |
56 main_thread_missed_last_deadline_(false), | 57 main_thread_missed_last_deadline_(false), |
57 skip_next_begin_main_frame_to_reduce_latency_(false), | 58 skip_next_begin_main_frame_to_reduce_latency_(false), |
58 defer_commits_(false), | 59 defer_commits_(false), |
59 video_needs_begin_frames_(false), | 60 video_needs_begin_frames_(false), |
60 last_commit_had_no_updates_(false), | 61 last_commit_had_no_updates_(false), |
61 wait_for_ready_to_draw_(false), | 62 wait_for_ready_to_draw_(false), |
62 did_draw_in_last_frame_(false), | 63 did_draw_in_last_frame_(false), |
63 did_submit_in_last_frame_(false) {} | 64 did_submit_in_last_frame_(false), |
65 needs_impl_side_invalidation_(false), | |
66 previous_pending_tree_was_impl_side_(false), | |
67 current_pending_tree_is_impl_side_(false) {} | |
64 | 68 |
65 const char* SchedulerStateMachine::CompositorFrameSinkStateToString( | 69 const char* SchedulerStateMachine::CompositorFrameSinkStateToString( |
66 CompositorFrameSinkState state) { | 70 CompositorFrameSinkState state) { |
67 switch (state) { | 71 switch (state) { |
68 case COMPOSITOR_FRAME_SINK_NONE: | 72 case COMPOSITOR_FRAME_SINK_NONE: |
69 return "COMPOSITOR_FRAME_SINK_NONE"; | 73 return "COMPOSITOR_FRAME_SINK_NONE"; |
70 case COMPOSITOR_FRAME_SINK_ACTIVE: | 74 case COMPOSITOR_FRAME_SINK_ACTIVE: |
71 return "COMPOSITOR_FRAME_SINK_ACTIVE"; | 75 return "COMPOSITOR_FRAME_SINK_ACTIVE"; |
72 case COMPOSITOR_FRAME_SINK_CREATING: | 76 case COMPOSITOR_FRAME_SINK_CREATING: |
73 return "COMPOSITOR_FRAME_SINK_CREATING"; | 77 return "COMPOSITOR_FRAME_SINK_CREATING"; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 case ACTION_DRAW_FORCED: | 174 case ACTION_DRAW_FORCED: |
171 return "ACTION_DRAW_FORCED"; | 175 return "ACTION_DRAW_FORCED"; |
172 case ACTION_DRAW_ABORT: | 176 case ACTION_DRAW_ABORT: |
173 return "ACTION_DRAW_ABORT"; | 177 return "ACTION_DRAW_ABORT"; |
174 case ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION: | 178 case ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION: |
175 return "ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION"; | 179 return "ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION"; |
176 case ACTION_PREPARE_TILES: | 180 case ACTION_PREPARE_TILES: |
177 return "ACTION_PREPARE_TILES"; | 181 return "ACTION_PREPARE_TILES"; |
178 case ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK: | 182 case ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK: |
179 return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK"; | 183 return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK"; |
184 case ACTION_PERFORM_IMPL_SIDE_INVALIDATION: | |
185 return "ACTION_PERFORM_IMPL_SIDE_INVALIDATION"; | |
180 } | 186 } |
181 NOTREACHED(); | 187 NOTREACHED(); |
182 return "???"; | 188 return "???"; |
183 } | 189 } |
184 | 190 |
185 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 191 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
186 SchedulerStateMachine::AsValue() const { | 192 SchedulerStateMachine::AsValue() const { |
187 std::unique_ptr<base::trace_event::TracedValue> state( | 193 std::unique_ptr<base::trace_event::TracedValue> state( |
188 new base::trace_event::TracedValue()); | 194 new base::trace_event::TracedValue()); |
189 AsValueInto(state.get()); | 195 AsValueInto(state.get()); |
(...skipping 23 matching lines...) Expand all Loading... | |
213 state->SetInteger("last_frame_number_draw_performed", | 219 state->SetInteger("last_frame_number_draw_performed", |
214 last_frame_number_draw_performed_); | 220 last_frame_number_draw_performed_); |
215 state->SetInteger("last_frame_number_begin_main_frame_sent", | 221 state->SetInteger("last_frame_number_begin_main_frame_sent", |
216 last_frame_number_begin_main_frame_sent_); | 222 last_frame_number_begin_main_frame_sent_); |
217 state->SetBoolean("funnel: draw_funnel", draw_funnel_); | 223 state->SetBoolean("funnel: draw_funnel", draw_funnel_); |
218 state->SetBoolean("funnel: send_begin_main_frame_funnel", | 224 state->SetBoolean("funnel: send_begin_main_frame_funnel", |
219 send_begin_main_frame_funnel_); | 225 send_begin_main_frame_funnel_); |
220 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); | 226 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); |
221 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel", | 227 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel", |
222 invalidate_compositor_frame_sink_funnel_); | 228 invalidate_compositor_frame_sink_funnel_); |
229 state->SetBoolean("funnel: impl_side_invalidation_funnel", | |
230 impl_side_invalidation_funnel_); | |
223 state->SetInteger("consecutive_checkerboard_animations", | 231 state->SetInteger("consecutive_checkerboard_animations", |
224 consecutive_checkerboard_animations_); | 232 consecutive_checkerboard_animations_); |
225 state->SetInteger("pending_submit_frames_", pending_submit_frames_); | 233 state->SetInteger("pending_submit_frames_", pending_submit_frames_); |
226 state->SetInteger("submit_frames_with_current_compositor_frame_sink", | 234 state->SetInteger("submit_frames_with_current_compositor_frame_sink", |
227 submit_frames_with_current_compositor_frame_sink_); | 235 submit_frames_with_current_compositor_frame_sink_); |
228 state->SetBoolean("needs_redraw", needs_redraw_); | 236 state->SetBoolean("needs_redraw", needs_redraw_); |
229 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); | 237 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); |
230 state->SetBoolean("needs_begin_main_frame", needs_begin_main_frame_); | 238 state->SetBoolean("needs_begin_main_frame", needs_begin_main_frame_); |
231 state->SetBoolean("needs_one_begin_impl_frame", needs_one_begin_impl_frame_); | 239 state->SetBoolean("needs_one_begin_impl_frame", needs_one_begin_impl_frame_); |
232 state->SetBoolean("visible", visible_); | 240 state->SetBoolean("visible", visible_); |
(...skipping 15 matching lines...) Expand all Loading... | |
248 critical_begin_main_frame_to_activate_is_fast_); | 256 critical_begin_main_frame_to_activate_is_fast_); |
249 state->SetBoolean("main_thread_missed_last_deadline", | 257 state->SetBoolean("main_thread_missed_last_deadline", |
250 main_thread_missed_last_deadline_); | 258 main_thread_missed_last_deadline_); |
251 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 259 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
252 skip_next_begin_main_frame_to_reduce_latency_); | 260 skip_next_begin_main_frame_to_reduce_latency_); |
253 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); | 261 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); |
254 state->SetBoolean("defer_commits", defer_commits_); | 262 state->SetBoolean("defer_commits", defer_commits_); |
255 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); | 263 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); |
256 state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_); | 264 state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_); |
257 state->SetBoolean("did_submit_in_last_frame", did_submit_in_last_frame_); | 265 state->SetBoolean("did_submit_in_last_frame", did_submit_in_last_frame_); |
266 state->SetBoolean("needs_impl_side_invalidation", | |
267 needs_impl_side_invalidation_); | |
258 state->EndDictionary(); | 268 state->EndDictionary(); |
259 } | 269 } |
260 | 270 |
261 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { | 271 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { |
262 // Normally when |visible_| is false or |begin_frame_source_paused_| is true, | 272 // Normally when |visible_| is false or |begin_frame_source_paused_| is true, |
263 // pending activations will be forced and draws will be aborted. However, | 273 // pending activations will be forced and draws will be aborted. However, |
264 // when the embedder is Android WebView, software draws could be scheduled by | 274 // when the embedder is Android WebView, software draws could be scheduled by |
265 // the Android OS at any time and draws should not be aborted in this case. | 275 // the Android OS at any time and draws should not be aborted in this case. |
266 bool is_compositor_frame_sink_lost = | 276 bool is_compositor_frame_sink_lost = |
267 (compositor_frame_sink_state_ == COMPOSITOR_FRAME_SINK_NONE); | 277 (compositor_frame_sink_state_ == COMPOSITOR_FRAME_SINK_NONE); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
512 // and then periodically after that. Use a funnel to make sure we average | 522 // and then periodically after that. Use a funnel to make sure we average |
513 // one PrepareTiles per BeginImplFrame in the long run. | 523 // one PrepareTiles per BeginImplFrame in the long run. |
514 if (prepare_tiles_funnel_ > 0) | 524 if (prepare_tiles_funnel_ > 0) |
515 return false; | 525 return false; |
516 | 526 |
517 // Limiting to once per-frame is not enough, since we only want to | 527 // Limiting to once per-frame is not enough, since we only want to |
518 // prepare tiles _after_ draws. | 528 // prepare tiles _after_ draws. |
519 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 529 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
520 return false; | 530 return false; |
521 | 531 |
532 // If an impl-side invalidation request is pending and we are inside the | |
533 // deadline, then performing these invalidations will also do PrepareTiles. | |
534 if (needs_impl_side_invalidation_) | |
sunnyps
2017/02/23 00:33:21
Impl side invalidation will happen before prepare
Khushal
2017/02/23 01:25:43
Done.
sunnyps
2017/02/23 01:34:12
nit: Try moving this DCHECK to WillPrepareTiles. T
Khushal
2017/02/23 07:42:37
Actually on second look, I don't think this logic/
| |
535 return false; | |
536 | |
522 return needs_prepare_tiles_; | 537 return needs_prepare_tiles_; |
523 } | 538 } |
524 | 539 |
525 bool SchedulerStateMachine::ShouldInvalidateCompositorFrameSink() const { | 540 bool SchedulerStateMachine::ShouldInvalidateCompositorFrameSink() const { |
526 // Do not invalidate too many times in a frame. | 541 // Do not invalidate too many times in a frame. |
527 if (invalidate_compositor_frame_sink_funnel_) | 542 if (invalidate_compositor_frame_sink_funnel_) |
528 return false; | 543 return false; |
529 | 544 |
530 // Only the synchronous compositor requires invalidations. | 545 // Only the synchronous compositor requires invalidations. |
531 if (!settings_.using_synchronous_renderer_compositor) | 546 if (!settings_.using_synchronous_renderer_compositor) |
(...skipping 15 matching lines...) Expand all Loading... | |
547 if (ShouldCommit()) | 562 if (ShouldCommit()) |
548 return ACTION_COMMIT; | 563 return ACTION_COMMIT; |
549 if (ShouldDraw()) { | 564 if (ShouldDraw()) { |
550 if (PendingDrawsShouldBeAborted()) | 565 if (PendingDrawsShouldBeAborted()) |
551 return ACTION_DRAW_ABORT; | 566 return ACTION_DRAW_ABORT; |
552 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 567 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
553 return ACTION_DRAW_FORCED; | 568 return ACTION_DRAW_FORCED; |
554 else | 569 else |
555 return ACTION_DRAW_IF_POSSIBLE; | 570 return ACTION_DRAW_IF_POSSIBLE; |
556 } | 571 } |
572 if (ShouldPerformImplSideInvalidation()) | |
573 return ACTION_PERFORM_IMPL_SIDE_INVALIDATION; | |
557 if (ShouldPrepareTiles()) | 574 if (ShouldPrepareTiles()) |
558 return ACTION_PREPARE_TILES; | 575 return ACTION_PREPARE_TILES; |
559 if (ShouldSendBeginMainFrame()) | 576 if (ShouldSendBeginMainFrame()) |
560 return ACTION_SEND_BEGIN_MAIN_FRAME; | 577 return ACTION_SEND_BEGIN_MAIN_FRAME; |
561 if (ShouldInvalidateCompositorFrameSink()) | 578 if (ShouldInvalidateCompositorFrameSink()) |
562 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK; | 579 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK; |
563 if (ShouldBeginCompositorFrameSinkCreation()) | 580 if (ShouldBeginCompositorFrameSinkCreation()) |
564 return ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION; | 581 return ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION; |
565 return ACTION_NONE; | 582 return ACTION_NONE; |
566 } | 583 } |
567 | 584 |
585 bool SchedulerStateMachine::ShouldPerformImplSideInvalidation() const { | |
586 if (!needs_impl_side_invalidation_) | |
587 return false; | |
588 | |
589 if (!CouldCreatePendingTree()) | |
590 return false; | |
591 | |
592 // If the main thread is ready to commit, the impl-side invalidations will be | |
593 // merged with the incoming main frame. | |
594 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT) | |
595 return false; | |
596 | |
597 // Don't invalidate too many times in the same frame. | |
598 if (impl_side_invalidation_funnel_) | |
599 return false; | |
600 | |
601 // If invalidations go to the active tree and we are waiting for the previous | |
602 // frame to be drawn, submitted and acked. | |
603 if (settings_.commit_to_active_tree && | |
604 (active_tree_needs_first_draw_ || IsDrawThrottled())) { | |
605 return false; | |
606 } | |
607 | |
608 // If we are inside the deadline and an impl-side invalidation request is | |
609 // still pending, do it now. We restrict performing impl-side invalidations | |
610 // until the deadline to give the main thread a chance to respond to a sent | |
611 // BeginMainFrame. If the main thread responds with a commit, we know the | |
612 // invalidations will have been merged with the main frame. | |
613 // If the commit was aborted, or the main thread fails to respond within the | |
614 // deadline, then we create a pending tree for impl-side invalidations now. | |
615 // This also checks to make sure that the |prepare_tiles_funnel_| is not full, | |
616 // since impl-side invalidations will cause a PrepareTiles. | |
617 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && | |
618 prepare_tiles_funnel_ == 0) | |
sunnyps
2017/02/23 00:33:21
nit: braces
Khushal
2017/02/23 01:25:43
Done.
| |
619 return true; | |
620 | |
621 // Wait till the deadline to perform impl-side invalidations. | |
622 return false; | |
623 } | |
624 | |
625 void SchedulerStateMachine::WillPerformImplSideInvalidation() { | |
626 current_pending_tree_is_impl_side_ = true; | |
627 WillPerformImplSideInvalidationInternal(); | |
628 } | |
629 | |
630 void SchedulerStateMachine::WillPerformImplSideInvalidationInternal() { | |
631 DCHECK(needs_impl_side_invalidation_); | |
632 DCHECK(!has_pending_tree_); | |
633 | |
634 needs_impl_side_invalidation_ = false; | |
635 has_pending_tree_ = true; | |
sunnyps
2017/02/23 00:33:21
For invalidating active tree (commit_to_active_tre
Khushal
2017/02/23 01:25:43
Yup, sending the activation signal will happen in
| |
636 impl_side_invalidation_funnel_ = true; | |
637 } | |
638 | |
639 bool SchedulerStateMachine::CouldCreatePendingTree() const { | |
640 // Can't create a new pending tree till the current one is activated. | |
641 if (has_pending_tree_) | |
642 return false; | |
643 | |
644 // Can't make frames while we're invisible. | |
645 if (!visible_) | |
646 return false; | |
647 | |
648 // If the BeginFrameSource is paused, we will not be able to make any impl | |
649 // frames. | |
650 if (begin_frame_source_paused_) | |
651 return false; | |
652 | |
653 // Don't create a pending tree till a frame sink is initialized. | |
654 if (!HasInitializedCompositorFrameSink()) | |
655 return false; | |
656 | |
657 return true; | |
658 } | |
659 | |
568 void SchedulerStateMachine::WillSendBeginMainFrame() { | 660 void SchedulerStateMachine::WillSendBeginMainFrame() { |
569 DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled); | 661 DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled); |
570 DCHECK(visible_); | 662 DCHECK(visible_); |
571 DCHECK(!begin_frame_source_paused_); | 663 DCHECK(!begin_frame_source_paused_); |
572 DCHECK(!send_begin_main_frame_funnel_); | 664 DCHECK(!send_begin_main_frame_funnel_); |
573 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_SENT; | 665 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_SENT; |
574 needs_begin_main_frame_ = false; | 666 needs_begin_main_frame_ = false; |
575 send_begin_main_frame_funnel_ = true; | 667 send_begin_main_frame_funnel_ = true; |
576 last_frame_number_begin_main_frame_sent_ = current_frame_number_; | 668 last_frame_number_begin_main_frame_sent_ = current_frame_number_; |
577 } | 669 } |
578 | 670 |
579 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { | 671 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { |
580 DCHECK(!has_pending_tree_ || | 672 DCHECK(!has_pending_tree_ || |
581 (settings_.main_frame_before_activation_enabled && | 673 (settings_.main_frame_before_activation_enabled && |
582 commit_has_no_updates)); | 674 commit_has_no_updates)); |
583 commit_count_++; | 675 commit_count_++; |
584 last_commit_had_no_updates_ = commit_has_no_updates; | 676 last_commit_had_no_updates_ = commit_has_no_updates; |
585 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; | 677 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; |
586 | 678 |
587 if (!commit_has_no_updates) { | 679 if (!commit_has_no_updates) { |
680 // If there was a commit, the impl-side invalidations will be merged with | |
681 // it. We always fill the impl-side invalidation funnel here, even if no | |
682 // request was currently pending, to defer creating another pending tree and | |
683 // performing PrepareTiles until the next frame, in case the invalidation | |
684 // request is received after the commit. | |
685 if (needs_impl_side_invalidation_) | |
686 WillPerformImplSideInvalidationInternal(); | |
687 impl_side_invalidation_funnel_ = true; | |
688 | |
588 // Pending tree only exists if commit had updates. | 689 // Pending tree only exists if commit had updates. |
589 has_pending_tree_ = true; | 690 has_pending_tree_ = true; |
590 pending_tree_is_ready_for_activation_ = false; | 691 pending_tree_is_ready_for_activation_ = false; |
591 wait_for_ready_to_draw_ = settings_.commit_to_active_tree; | 692 wait_for_ready_to_draw_ = settings_.commit_to_active_tree; |
592 } | 693 } |
593 | 694 |
594 // Update state related to forced draws. | 695 // Update state related to forced draws. |
595 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { | 696 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { |
596 forced_redraw_state_ = has_pending_tree_ | 697 forced_redraw_state_ = has_pending_tree_ |
597 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION | 698 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION |
(...skipping 14 matching lines...) Expand all Loading... | |
612 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION) | 713 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION) |
613 compositor_frame_sink_state_ = COMPOSITOR_FRAME_SINK_ACTIVE; | 714 compositor_frame_sink_state_ = COMPOSITOR_FRAME_SINK_ACTIVE; |
614 | 715 |
615 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) | 716 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) |
616 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 717 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
617 | 718 |
618 has_pending_tree_ = false; | 719 has_pending_tree_ = false; |
619 pending_tree_is_ready_for_activation_ = false; | 720 pending_tree_is_ready_for_activation_ = false; |
620 active_tree_needs_first_draw_ = true; | 721 active_tree_needs_first_draw_ = true; |
621 needs_redraw_ = true; | 722 needs_redraw_ = true; |
723 | |
724 previous_pending_tree_was_impl_side_ = current_pending_tree_is_impl_side_; | |
725 current_pending_tree_is_impl_side_ = false; | |
622 } | 726 } |
623 | 727 |
624 void SchedulerStateMachine::WillDrawInternal() { | 728 void SchedulerStateMachine::WillDrawInternal() { |
625 // If a new active tree is pending after the one we are about to draw, | 729 // If a new active tree is pending after the one we are about to draw, |
626 // the main thread is in a high latency mode. | 730 // the main thread is in a high latency mode. |
627 // main_thread_missed_last_deadline_ is here in addition to | 731 // main_thread_missed_last_deadline_ is here in addition to |
628 // OnBeginImplFrameIdle for cases where the scheduler aborts draws outside | 732 // OnBeginImplFrameIdle for cases where the scheduler aborts draws outside |
629 // of the deadline. | 733 // of the deadline. |
630 main_thread_missed_last_deadline_ = CommitPending() || has_pending_tree_; | 734 main_thread_missed_last_deadline_ = CommitPending() || has_pending_tree_; |
631 | 735 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
682 | 786 |
683 void SchedulerStateMachine::WillDraw() { | 787 void SchedulerStateMachine::WillDraw() { |
684 DCHECK(!draw_funnel_); | 788 DCHECK(!draw_funnel_); |
685 WillDrawInternal(); | 789 WillDrawInternal(); |
686 } | 790 } |
687 | 791 |
688 void SchedulerStateMachine::DidDraw(DrawResult draw_result) { | 792 void SchedulerStateMachine::DidDraw(DrawResult draw_result) { |
689 DidDrawInternal(draw_result); | 793 DidDrawInternal(draw_result); |
690 } | 794 } |
691 | 795 |
796 void SchedulerStateMachine::SetNeedsImplSideInvalidation() { | |
797 needs_impl_side_invalidation_ = true; | |
798 } | |
799 | |
692 void SchedulerStateMachine::AbortDraw() { | 800 void SchedulerStateMachine::AbortDraw() { |
693 // Pretend like the draw was successful. | 801 // Pretend like the draw was successful. |
694 // Note: We may abort at any time and cannot DCHECK that | 802 // Note: We may abort at any time and cannot DCHECK that |
695 // we haven't drawn in or swapped in the last frame here. | 803 // we haven't drawn in or swapped in the last frame here. |
696 WillDrawInternal(); | 804 WillDrawInternal(); |
697 DidDrawInternal(DRAW_ABORTED_DRAINING_PIPELINE); | 805 DidDrawInternal(DRAW_ABORTED_DRAINING_PIPELINE); |
698 } | 806 } |
699 | 807 |
700 void SchedulerStateMachine::WillPrepareTiles() { | 808 void SchedulerStateMachine::WillPrepareTiles() { |
701 needs_prepare_tiles_ = false; | 809 needs_prepare_tiles_ = false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 | 868 |
761 // These are the cases where we require a BeginFrame message to make progress | 869 // These are the cases where we require a BeginFrame message to make progress |
762 // on requested actions. | 870 // on requested actions. |
763 bool SchedulerStateMachine::BeginFrameRequiredForAction() const { | 871 bool SchedulerStateMachine::BeginFrameRequiredForAction() const { |
764 // The forced draw respects our normal draw scheduling, so we need to | 872 // The forced draw respects our normal draw scheduling, so we need to |
765 // request a BeginImplFrame for it. | 873 // request a BeginImplFrame for it. |
766 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 874 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
767 return true; | 875 return true; |
768 | 876 |
769 return needs_redraw_ || needs_one_begin_impl_frame_ || | 877 return needs_redraw_ || needs_one_begin_impl_frame_ || |
770 (needs_begin_main_frame_ && !defer_commits_); | 878 (needs_begin_main_frame_ && !defer_commits_) || |
879 needs_impl_side_invalidation_; | |
771 } | 880 } |
772 | 881 |
773 // These are cases where we are very likely want a BeginFrame message in the | 882 // These are cases where we are very likely want a BeginFrame message in the |
774 // near future. Proactively requesting the BeginImplFrame helps hide the round | 883 // near future. Proactively requesting the BeginImplFrame helps hide the round |
775 // trip latency of the SetNeedsBeginFrame request that has to go to the | 884 // trip latency of the SetNeedsBeginFrame request that has to go to the |
776 // Browser. | 885 // Browser. |
777 // This includes things like drawing soon, but might not actually have a new | 886 // This includes things like drawing soon, but might not actually have a new |
778 // frame to draw when we receive the next BeginImplFrame. | 887 // frame to draw when we receive the next BeginImplFrame. |
779 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { | 888 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
780 // Do not be proactive when invisible. | 889 // Do not be proactive when invisible. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 current_frame_number_++; | 929 current_frame_number_++; |
821 | 930 |
822 last_commit_had_no_updates_ = false; | 931 last_commit_had_no_updates_ = false; |
823 did_draw_in_last_frame_ = false; | 932 did_draw_in_last_frame_ = false; |
824 did_submit_in_last_frame_ = false; | 933 did_submit_in_last_frame_ = false; |
825 needs_one_begin_impl_frame_ = false; | 934 needs_one_begin_impl_frame_ = false; |
826 | 935 |
827 // Clear funnels for any actions we perform during the frame. | 936 // Clear funnels for any actions we perform during the frame. |
828 send_begin_main_frame_funnel_ = false; | 937 send_begin_main_frame_funnel_ = false; |
829 invalidate_compositor_frame_sink_funnel_ = false; | 938 invalidate_compositor_frame_sink_funnel_ = false; |
939 impl_side_invalidation_funnel_ = false; | |
830 | 940 |
831 // "Drain" the PrepareTiles funnel. | 941 // "Drain" the PrepareTiles funnel. |
832 if (prepare_tiles_funnel_ > 0) | 942 if (prepare_tiles_funnel_ > 0) |
833 prepare_tiles_funnel_--; | 943 prepare_tiles_funnel_--; |
834 } | 944 } |
835 | 945 |
836 void SchedulerStateMachine::OnBeginImplFrameDeadline() { | 946 void SchedulerStateMachine::OnBeginImplFrameDeadline() { |
837 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 947 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
838 | 948 |
839 // Clear funnels for any actions we perform during the deadline. | 949 // Clear funnels for any actions we perform during the deadline. |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 case COMPOSITOR_FRAME_SINK_ACTIVE: | 1213 case COMPOSITOR_FRAME_SINK_ACTIVE: |
1104 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: | 1214 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: |
1105 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: | 1215 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: |
1106 return true; | 1216 return true; |
1107 } | 1217 } |
1108 NOTREACHED(); | 1218 NOTREACHED(); |
1109 return false; | 1219 return false; |
1110 } | 1220 } |
1111 | 1221 |
1112 } // namespace cc | 1222 } // namespace cc |
OLD | NEW |