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

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

Issue 817603002: cc: Make scheduling be driven by vsync for android webview. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix misc bugs introduced in last two patches Created 5 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_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"
11 #include "base/trace_event/trace_event_argument.h" 11 #include "base/trace_event/trace_event_argument.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
14 14
15 namespace cc { 15 namespace cc {
16 16
17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
18 : settings_(settings), 18 : settings_(settings),
19 output_surface_state_(OUTPUT_SURFACE_LOST), 19 output_surface_state_(OUTPUT_SURFACE_LOST),
20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), 20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
21 commit_state_(COMMIT_STATE_IDLE), 21 commit_state_(COMMIT_STATE_IDLE),
22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
23 commit_count_(0), 23 commit_count_(0),
24 current_frame_number_(0), 24 current_frame_number_(0),
25 last_frame_number_animate_performed_(-1), 25 last_frame_number_animate_performed_(-1),
26 last_frame_number_swap_performed_(-1), 26 last_frame_number_swap_performed_(-1),
27 last_frame_number_swap_requested_(-1), 27 last_frame_number_swap_requested_(-1),
28 last_frame_number_begin_main_frame_sent_(-1), 28 last_frame_number_begin_main_frame_sent_(-1),
29 last_frame_number_invalidate_output_surface_performed_(-1),
29 prepare_tiles_funnel_(0), 30 prepare_tiles_funnel_(0),
30 consecutive_checkerboard_animations_(0), 31 consecutive_checkerboard_animations_(0),
31 max_pending_swaps_(1), 32 max_pending_swaps_(1),
32 pending_swaps_(0), 33 pending_swaps_(0),
33 needs_redraw_(false), 34 needs_redraw_(false),
34 needs_animate_(false), 35 needs_animate_(false),
35 needs_prepare_tiles_(false), 36 needs_prepare_tiles_(false),
36 needs_commit_(false), 37 needs_commit_(false),
37 inside_poll_for_anticipated_draw_triggers_(false),
38 visible_(false), 38 visible_(false),
39 can_start_(false), 39 can_start_(false),
40 can_draw_(false), 40 can_draw_(false),
41 has_pending_tree_(false), 41 has_pending_tree_(false),
42 pending_tree_is_ready_for_activation_(false), 42 pending_tree_is_ready_for_activation_(false),
43 active_tree_needs_first_draw_(false), 43 active_tree_needs_first_draw_(false),
44 did_commit_after_animating_(false), 44 did_commit_after_animating_(false),
45 did_create_and_initialize_first_output_surface_(false), 45 did_create_and_initialize_first_output_surface_(false),
46 impl_latency_takes_priority_(false), 46 impl_latency_takes_priority_(false),
47 skip_next_begin_main_frame_to_reduce_latency_(false), 47 skip_next_begin_main_frame_to_reduce_latency_(false),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING"; 79 return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING";
80 case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME: 80 case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME:
81 return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME"; 81 return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME";
82 case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE: 82 case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE:
83 return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE"; 83 return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE";
84 } 84 }
85 NOTREACHED(); 85 NOTREACHED();
86 return "???"; 86 return "???";
87 } 87 }
88 88
89 const char* SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
90 BeginImplFrameDeadlineMode mode) {
91 switch (mode) {
92 case BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_SYNCHRONOUS:
93 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_SYNCHRONOUS";
94 case BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_ASYNCHRONOUS:
95 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_ASYNCHRONOUS";
96 case BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
97 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR";
98 case BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
99 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE";
100 }
101 NOTREACHED();
102 return "???";
103 }
104
89 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 105 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
90 switch (state) { 106 switch (state) {
91 case COMMIT_STATE_IDLE: 107 case COMMIT_STATE_IDLE:
92 return "COMMIT_STATE_IDLE"; 108 return "COMMIT_STATE_IDLE";
93 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT: 109 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT:
94 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT"; 110 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT";
95 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED: 111 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED:
96 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED"; 112 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED";
97 case COMMIT_STATE_READY_TO_COMMIT: 113 case COMMIT_STATE_READY_TO_COMMIT:
98 return "COMMIT_STATE_READY_TO_COMMIT"; 114 return "COMMIT_STATE_READY_TO_COMMIT";
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: 152 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
137 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; 153 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
138 case ACTION_DRAW_AND_SWAP_FORCED: 154 case ACTION_DRAW_AND_SWAP_FORCED:
139 return "ACTION_DRAW_AND_SWAP_FORCED"; 155 return "ACTION_DRAW_AND_SWAP_FORCED";
140 case ACTION_DRAW_AND_SWAP_ABORT: 156 case ACTION_DRAW_AND_SWAP_ABORT:
141 return "ACTION_DRAW_AND_SWAP_ABORT"; 157 return "ACTION_DRAW_AND_SWAP_ABORT";
142 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 158 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
143 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 159 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
144 case ACTION_PREPARE_TILES: 160 case ACTION_PREPARE_TILES:
145 return "ACTION_PREPARE_TILES"; 161 return "ACTION_PREPARE_TILES";
162 case ACTION_INVALIDATE_OUTPUT_SURFACE:
163 return "ACTION_INVALIDATE_OUTPUT_SURFACE";
146 } 164 }
147 NOTREACHED(); 165 NOTREACHED();
148 return "???"; 166 return "???";
149 } 167 }
150 168
151 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 169 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
152 SchedulerStateMachine::AsValue() const { 170 SchedulerStateMachine::AsValue() const {
153 scoped_refptr<base::trace_event::TracedValue> state = 171 scoped_refptr<base::trace_event::TracedValue> state =
154 new base::trace_event::TracedValue(); 172 new base::trace_event::TracedValue();
155 AsValueInto(state.get(), gfx::FrameTime::Now()); 173 AsValueInto(state.get(), gfx::FrameTime::Now());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 254 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
237 skip_next_begin_main_frame_to_reduce_latency_); 255 skip_next_begin_main_frame_to_reduce_latency_);
238 state->SetBoolean("continuous_painting", continuous_painting_); 256 state->SetBoolean("continuous_painting", continuous_painting_);
239 state->SetBoolean("impl_latency_takes_priority_on_battery", 257 state->SetBoolean("impl_latency_takes_priority_on_battery",
240 impl_latency_takes_priority_on_battery_); 258 impl_latency_takes_priority_on_battery_);
241 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 259 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
242 state->SetBoolean("defer_commits", defer_commits_); 260 state->SetBoolean("defer_commits", defer_commits_);
243 state->EndDictionary(); 261 state->EndDictionary();
244 } 262 }
245 263
246 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { 264 void SchedulerStateMachine::AdvanceFrame() {
247 current_frame_number_++; 265 current_frame_number_++;
248 266
249 // "Drain" the PrepareTiles funnel. 267 // "Drain" the PrepareTiles funnel.
250 if (prepare_tiles_funnel_ > 0) 268 if (prepare_tiles_funnel_ > 0)
251 prepare_tiles_funnel_--; 269 prepare_tiles_funnel_--;
252 270
253 skip_begin_main_frame_to_reduce_latency_ = 271 skip_begin_main_frame_to_reduce_latency_ =
254 skip_next_begin_main_frame_to_reduce_latency_; 272 skip_next_begin_main_frame_to_reduce_latency_;
255 skip_next_begin_main_frame_to_reduce_latency_ = false; 273 skip_next_begin_main_frame_to_reduce_latency_ = false;
256 } 274 }
257 275
258 bool SchedulerStateMachine::HasAnimatedThisFrame() const { 276 bool SchedulerStateMachine::HasAnimatedThisFrame() const {
259 return last_frame_number_animate_performed_ == current_frame_number_; 277 return last_frame_number_animate_performed_ == current_frame_number_;
260 } 278 }
261 279
262 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { 280 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
263 return current_frame_number_ == 281 return current_frame_number_ ==
264 last_frame_number_begin_main_frame_sent_; 282 last_frame_number_begin_main_frame_sent_;
265 } 283 }
266 284
267 bool SchedulerStateMachine::HasSwappedThisFrame() const { 285 bool SchedulerStateMachine::HasSwappedThisFrame() const {
268 return current_frame_number_ == last_frame_number_swap_performed_; 286 return current_frame_number_ == last_frame_number_swap_performed_;
269 } 287 }
270 288
271 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const { 289 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const {
272 return current_frame_number_ == last_frame_number_swap_requested_; 290 return current_frame_number_ == last_frame_number_swap_requested_;
273 } 291 }
274 292
293 bool SchedulerStateMachine::HasInvalidatedOutputSurfaceThisFrame() const {
294 return current_frame_number_ ==
295 last_frame_number_invalidate_output_surface_performed_;
296 }
297
275 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 298 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
276 // These are all the cases where we normally cannot or do not want to draw 299 // These are all the cases where we normally cannot or do not want to draw
277 // but, if needs_redraw_ is true and we do not draw to make forward progress, 300 // but, if needs_redraw_ is true and we do not draw to make forward progress,
278 // we might deadlock with the main thread. 301 // we might deadlock with the main thread.
279 // This should be a superset of PendingActivationsShouldBeForced() since 302 // This should be a superset of PendingActivationsShouldBeForced() since
280 // activation of the pending tree is blocked by drawing of the active tree and 303 // activation of the pending tree is blocked by drawing of the active tree and
281 // the main thread might be blocked on activation of the most recent commit. 304 // the main thread might be blocked on activation of the most recent commit.
282 if (PendingActivationsShouldBeForced()) 305 if (PendingActivationsShouldBeForced())
283 return true; 306 return true;
284 307
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 // are initializing the output surface. 352 // are initializing the output surface.
330 if (active_tree_needs_first_draw_ || has_pending_tree_) 353 if (active_tree_needs_first_draw_ || has_pending_tree_)
331 return false; 354 return false;
332 355
333 // We need to create the output surface if we don't have one and we haven't 356 // We need to create the output surface if we don't have one and we haven't
334 // started creating one yet. 357 // started creating one yet.
335 return output_surface_state_ == OUTPUT_SURFACE_LOST; 358 return output_surface_state_ == OUTPUT_SURFACE_LOST;
336 } 359 }
337 360
338 bool SchedulerStateMachine::ShouldDraw() const { 361 bool SchedulerStateMachine::ShouldDraw() const {
362 // In the synchronous compositor mode, draw only when asked to.
363 if (settings_.using_synchronous_renderer_compositor &&
364 begin_impl_frame_args_.type != BeginFrameArgs::SYNCHRONOUS_DRAW)
365 return false;
366
339 // If we need to abort draws, we should do so ASAP since the draw could 367 // If we need to abort draws, we should do so ASAP since the draw could
340 // be blocking other important actions (like output surface initialization), 368 // be blocking other important actions (like output surface initialization),
341 // from occuring. If we are waiting for the first draw, then perfom the 369 // from occuring. If we are waiting for the first draw, then perfom the
342 // aborted draw to keep things moving. If we are not waiting for the first 370 // aborted draw to keep things moving. If we are not waiting for the first
343 // draw however, we don't want to abort for no reason. 371 // draw however, we don't want to abort for no reason.
344 if (PendingDrawsShouldBeAborted()) 372 if (PendingDrawsShouldBeAborted())
345 return active_tree_needs_first_draw_; 373 return active_tree_needs_first_draw_;
346 374
347 // Don't draw if we are waiting on the first commit after a surface. 375 // Don't draw if we are waiting on the first commit after a surface.
348 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 376 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 520 }
493 521
494 bool SchedulerStateMachine::ShouldPrepareTiles() const { 522 bool SchedulerStateMachine::ShouldPrepareTiles() const {
495 // PrepareTiles only really needs to be called immediately after commit 523 // PrepareTiles only really needs to be called immediately after commit
496 // and then periodically after that. Use a funnel to make sure we average 524 // and then periodically after that. Use a funnel to make sure we average
497 // one PrepareTiles per BeginImplFrame in the long run. 525 // one PrepareTiles per BeginImplFrame in the long run.
498 if (prepare_tiles_funnel_ > 0) 526 if (prepare_tiles_funnel_ > 0)
499 return false; 527 return false;
500 528
501 // Limiting to once per-frame is not enough, since we only want to 529 // Limiting to once per-frame is not enough, since we only want to
502 // prepare tiles _after_ draws. Polling for draw triggers and 530 // prepare tiles _after_ draws.
503 // begin-frame are mutually exclusive, so we limit to these two cases. 531 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
504 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
505 !inside_poll_for_anticipated_draw_triggers_)
506 return false; 532 return false;
533
507 return needs_prepare_tiles_; 534 return needs_prepare_tiles_;
508 } 535 }
509 536
537 bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const {
538 // Only the synchronous compositor requires invalidations.
539 if (!settings_.using_synchronous_renderer_compositor)
540 return false;
541
542 // Invalidations are only performed inside a BeginFrame deadline.
543 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
544 return false;
545
546 // Invalidate the output surface only once per frame.
547 if (HasInvalidatedOutputSurfaceThisFrame())
548 return false;
549
550 return needs_redraw_;
551 }
552
510 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 553 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
511 if (ShouldActivatePendingTree()) 554 if (ShouldActivatePendingTree())
512 return ACTION_ACTIVATE_SYNC_TREE; 555 return ACTION_ACTIVATE_SYNC_TREE;
513 if (ShouldCommit()) 556 if (ShouldCommit())
514 return ACTION_COMMIT; 557 return ACTION_COMMIT;
515 if (ShouldAnimate()) 558 if (ShouldAnimate())
516 return ACTION_ANIMATE; 559 return ACTION_ANIMATE;
517 if (ShouldDraw()) { 560 if (ShouldDraw()) {
518 if (PendingDrawsShouldBeAborted()) 561 if (PendingDrawsShouldBeAborted())
519 return ACTION_DRAW_AND_SWAP_ABORT; 562 return ACTION_DRAW_AND_SWAP_ABORT;
520 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 563 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
521 return ACTION_DRAW_AND_SWAP_FORCED; 564 return ACTION_DRAW_AND_SWAP_FORCED;
522 else 565 else
523 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; 566 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
524 } 567 }
525 if (ShouldPrepareTiles()) 568 if (ShouldPrepareTiles())
526 return ACTION_PREPARE_TILES; 569 return ACTION_PREPARE_TILES;
527 if (ShouldSendBeginMainFrame()) 570 if (ShouldSendBeginMainFrame())
528 return ACTION_SEND_BEGIN_MAIN_FRAME; 571 return ACTION_SEND_BEGIN_MAIN_FRAME;
572 if (ShouldInvalidateOutputSurface())
573 return ACTION_INVALIDATE_OUTPUT_SURFACE;
529 if (ShouldBeginOutputSurfaceCreation()) 574 if (ShouldBeginOutputSurfaceCreation())
530 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 575 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
531 return ACTION_NONE; 576 return ACTION_NONE;
532 } 577 }
533 578
534 void SchedulerStateMachine::UpdateState(Action action) { 579 void SchedulerStateMachine::UpdateState(Action action) {
535 switch (action) { 580 switch (action) {
536 case ACTION_NONE: 581 case ACTION_NONE:
537 return; 582 return;
538 583
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 // The pipeline should be flushed entirely before we start output 631 // The pipeline should be flushed entirely before we start output
587 // surface creation to avoid complicated corner cases. 632 // surface creation to avoid complicated corner cases.
588 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 633 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
589 DCHECK(!has_pending_tree_); 634 DCHECK(!has_pending_tree_);
590 DCHECK(!active_tree_needs_first_draw_); 635 DCHECK(!active_tree_needs_first_draw_);
591 return; 636 return;
592 637
593 case ACTION_PREPARE_TILES: 638 case ACTION_PREPARE_TILES:
594 UpdateStateOnPrepareTiles(); 639 UpdateStateOnPrepareTiles();
595 return; 640 return;
641
642 case ACTION_INVALIDATE_OUTPUT_SURFACE:
643 last_frame_number_invalidate_output_surface_performed_ =
644 current_frame_number_;
645 return;
596 } 646 }
597 } 647 }
598 648
599 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { 649 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
600 commit_count_++; 650 commit_count_++;
601 651
602 if (!commit_has_no_updates && HasAnimatedThisFrame()) 652 if (!commit_has_no_updates && HasAnimatedThisFrame())
603 did_commit_after_animating_ = true; 653 did_commit_after_animating_ = true;
604 654
605 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { 655 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 return children_need_begin_frames_; 749 return children_need_begin_frames_;
700 750
701 return false; 751 return false;
702 } 752 }
703 753
704 bool SchedulerStateMachine::BeginFrameNeeded() const { 754 bool SchedulerStateMachine::BeginFrameNeeded() const {
705 // We can't handle BeginFrames when output surface isn't initialized. 755 // We can't handle BeginFrames when output surface isn't initialized.
706 // TODO(brianderson): Support output surface creation inside a BeginFrame. 756 // TODO(brianderson): Support output surface creation inside a BeginFrame.
707 if (!HasInitializedOutputSurface()) 757 if (!HasInitializedOutputSurface())
708 return false; 758 return false;
709 759 return (BeginFrameNeededToAnimateOrDraw() || BeginFrameNeededForChildren() ||
710 if (SupportsProactiveBeginFrame()) { 760 ProactiveBeginFrameWanted());
711 return (BeginFrameNeededToAnimateOrDraw() ||
712 BeginFrameNeededForChildren() ||
713 ProactiveBeginFrameWanted());
714 }
715
716 // Proactive BeginFrames are bad for the synchronous compositor because we
717 // have to draw when we get the BeginFrame and could end up drawing many
718 // duplicate frames if our new frame isn't ready in time.
719 // To poll for state with the synchronous compositor without having to draw,
720 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
721 // Synchronous compositor doesn't have a browser.
722 DCHECK(!children_need_begin_frames_);
723 return BeginFrameNeededToAnimateOrDraw();
724 } 761 }
725 762
726 bool SchedulerStateMachine::ShouldSetNeedsBeginFrames( 763 bool SchedulerStateMachine::ShouldSetNeedsBeginFrames(
727 bool frame_source_needs_begin_frames) const { 764 bool frame_source_needs_begin_frames) const {
728 bool needs_begin_frame = BeginFrameNeeded(); 765 bool needs_begin_frame = BeginFrameNeeded();
729 766
730 // Never call SetNeedsBeginFrames if the frame source has the right value. 767 // Never call SetNeedsBeginFrames if the frame source has the right value.
731 if (needs_begin_frame == frame_source_needs_begin_frames) 768 if (needs_begin_frame == frame_source_needs_begin_frames)
732 return false; 769 return false;
733 770
734 // Always request the BeginFrame immediately if it's needed. 771 // Always request the BeginFrame immediately if it's needed.
735 if (needs_begin_frame) 772 if (needs_begin_frame)
736 return true; 773 return true;
737 774
738 // Stop requesting BeginFrames after a deadline. 775 // Stop requesting BeginFrames after a deadline.
739 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 776 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
740 return true; 777 return true;
741 778
742 // Stop requesting BeginFrames immediately when output surface is lost. 779 // Stop requesting BeginFrames immediately when output surface is lost.
743 if (!HasInitializedOutputSurface()) 780 if (!HasInitializedOutputSurface())
744 return true; 781 return true;
745 782
746 return false; 783 return false;
747 } 784 }
748 785
749 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
750 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
751 // ProactiveBeginFrameWanted when we are using the synchronous
752 // compositor.
753 if (!SupportsProactiveBeginFrame()) {
754 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
755 }
756
757 // Non synchronous compositors should rely on
758 // ProactiveBeginFrameWanted to poll for state instead.
759 return false;
760 }
761
762 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll
763 // for changes in it's draw state so it can request a BeginFrame when it's
764 // actually ready.
765 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
766 // It is undesirable to proactively request BeginFrames if we are
767 // using a synchronous compositor because we *must* draw for every
768 // BeginFrame, which could cause duplicate draws.
769 return !settings_.using_synchronous_renderer_compositor;
770 }
771
772 void SchedulerStateMachine::SetChildrenNeedBeginFrames( 786 void SchedulerStateMachine::SetChildrenNeedBeginFrames(
773 bool children_need_begin_frames) { 787 bool children_need_begin_frames) {
774 DCHECK(settings_.forward_begin_frames_to_children); 788 DCHECK(settings_.forward_begin_frames_to_children);
775 children_need_begin_frames_ = children_need_begin_frames; 789 children_need_begin_frames_ = children_need_begin_frames;
776 } 790 }
777 791
778 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { 792 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) {
779 defer_commits_ = defer_commits; 793 defer_commits_ = defer_commits;
780 } 794 }
781 795
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame 833 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
820 // provider and get sampled at an inopportune time, delaying the next 834 // provider and get sampled at an inopportune time, delaying the next
821 // BeginImplFrame. 835 // BeginImplFrame.
822 if (HasRequestedSwapThisFrame()) 836 if (HasRequestedSwapThisFrame())
823 return true; 837 return true;
824 838
825 return false; 839 return false;
826 } 840 }
827 841
828 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { 842 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) {
829 AdvanceCurrentFrameNumber();
830 begin_impl_frame_args_ = args; 843 begin_impl_frame_args_ = args;
844
845 // Advance frame for synchronous compositor on SYNCHRONOUS_ANIMATE only.
846 if (!settings_.using_synchronous_renderer_compositor ||
847 begin_impl_frame_args_.type == BeginFrameArgs::SYNCHRONOUS_ANIMATE)
848 AdvanceFrame();
849
831 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) 850 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE)
832 << AsValue()->ToString(); 851 << AsValue()->ToString();
833 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 852 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
834 } 853 }
835 854
836 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 855 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
837 DCHECK_EQ(begin_impl_frame_state_, 856 DCHECK_EQ(begin_impl_frame_state_,
838 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 857 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
839 << AsValue()->ToString(); 858 << AsValue()->ToString();
840 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 859 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
841 } 860 }
842 861
843 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 862 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
844 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 863 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
845 << AsValue()->ToString(); 864 << AsValue()->ToString();
846 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 865 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
847 } 866 }
848 867
849 void SchedulerStateMachine::OnBeginImplFrameIdle() { 868 void SchedulerStateMachine::OnBeginImplFrameIdle() {
850 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 869 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
851 << AsValue()->ToString(); 870 << AsValue()->ToString();
852 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; 871 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
853 } 872 }
854 873
855 SchedulerStateMachine::BeginImplFrameDeadlineMode 874 SchedulerStateMachine::BeginImplFrameDeadlineMode
856 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 875 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
857 if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 876 if (settings_.using_synchronous_renderer_compositor) {
858 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 877 // If the synchronous compositor wants to draw now.
878 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_SYNCHRONOUS;
879 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
880 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_ASYNCHRONOUS;
859 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { 881 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
860 // We have an animation or fast input path on the impl thread that wants 882 // We have an animation or fast input path on the impl thread that wants
861 // to draw, so don't wait too long for a new active tree. 883 // to draw, so don't wait too long for a new active tree.
862 // If we are swap throttled we should wait until we are unblocked. 884 // If we are swap throttled we should wait until we are unblocked.
863 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 885 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
864 } else { 886 } else {
865 // The impl thread doesn't have anything it wants to draw and we are just 887 // The impl thread doesn't have anything it wants to draw and we are just
866 // waiting for a new active tree or we are swap throttled. In short we are 888 // waiting for a new active tree or we are swap throttled. In short we are
867 // blocked. 889 // blocked.
868 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 890 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
869 } 891 }
870 } 892 }
871 893
872 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 894 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
873 const { 895 const {
874 // TODO(brianderson): This should take into account multiple commit sources. 896 // TODO(brianderson): This should take into account multiple commit sources.
875
876 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 897 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
877 return false; 898 return false;
878 899
879 // If we've lost the output surface, end the current BeginImplFrame ASAP 900 // If we've lost the output surface, end the current BeginImplFrame ASAP
880 // so we can start creating the next output surface. 901 // so we can start creating the next output surface.
881 if (output_surface_state_ == OUTPUT_SURFACE_LOST) 902 if (output_surface_state_ == OUTPUT_SURFACE_LOST)
882 return true; 903 return true;
883 904
884 // SwapAck throttle the deadline since we wont draw and swap anyway. 905 // SwapAck throttle the deadline since we wont draw and swap anyway.
885 if (pending_swaps_ >= max_pending_swaps_) 906 if (pending_swaps_ >= max_pending_swaps_)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 // which case the main thread is in a high latency mode. 966 // which case the main thread is in a high latency mode.
946 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && 967 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) &&
947 !HasSentBeginMainFrameThisFrame(); 968 !HasSentBeginMainFrameThisFrame();
948 } 969 }
949 970
950 // If the active tree needs its first draw in any other state, we know the 971 // If the active tree needs its first draw in any other state, we know the
951 // main thread is in a high latency mode. 972 // main thread is in a high latency mode.
952 return active_tree_needs_first_draw_; 973 return active_tree_needs_first_draw_;
953 } 974 }
954 975
955 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
956 AdvanceCurrentFrameNumber();
957 inside_poll_for_anticipated_draw_triggers_ = true;
958 }
959
960 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
961 inside_poll_for_anticipated_draw_triggers_ = false;
962 }
963
964 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 976 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
965 977
966 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 978 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
967 979
968 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 980 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
969 981
970 void SchedulerStateMachine::SetNeedsAnimate() { 982 void SchedulerStateMachine::SetNeedsAnimate() {
971 needs_animate_ = true; 983 needs_animate_ = true;
972 } 984 }
973 985
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 static_cast<int>(begin_impl_frame_state_), 1144 static_cast<int>(begin_impl_frame_state_),
1133 static_cast<int>(commit_state_), 1145 static_cast<int>(commit_state_),
1134 has_pending_tree_ ? 'T' : 'F', 1146 has_pending_tree_ ? 'T' : 'F',
1135 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1147 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1136 active_tree_needs_first_draw_ ? 'T' : 'F', 1148 active_tree_needs_first_draw_ ? 'T' : 'F',
1137 max_pending_swaps_, 1149 max_pending_swaps_,
1138 pending_swaps_); 1150 pending_swaps_);
1139 } 1151 }
1140 1152
1141 } // namespace cc 1153 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698