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

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: Created 6 years 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/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/debug/trace_event_argument.h" 8 #include "base/debug/trace_event_argument.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.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),
48 skip_begin_main_frame_to_reduce_latency_(false), 48 skip_begin_main_frame_to_reduce_latency_(false),
49 continuous_painting_(false), 49 continuous_painting_(false),
50 impl_latency_takes_priority_on_battery_(false), 50 impl_latency_takes_priority_on_battery_(false),
51 children_need_begin_frames_(false) { 51 children_need_begin_frames_(false),
52 output_surface_did_request_draw_(false) {
52 } 53 }
53 54
54 const char* SchedulerStateMachine::OutputSurfaceStateToString( 55 const char* SchedulerStateMachine::OutputSurfaceStateToString(
55 OutputSurfaceState state) { 56 OutputSurfaceState state) {
56 switch (state) { 57 switch (state) {
57 case OUTPUT_SURFACE_ACTIVE: 58 case OUTPUT_SURFACE_ACTIVE:
58 return "OUTPUT_SURFACE_ACTIVE"; 59 return "OUTPUT_SURFACE_ACTIVE";
59 case OUTPUT_SURFACE_LOST: 60 case OUTPUT_SURFACE_LOST:
60 return "OUTPUT_SURFACE_LOST"; 61 return "OUTPUT_SURFACE_LOST";
61 case OUTPUT_SURFACE_CREATING: 62 case OUTPUT_SURFACE_CREATING:
(...skipping 16 matching lines...) Expand all
78 return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING"; 79 return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING";
79 case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME: 80 case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME:
80 return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME"; 81 return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME";
81 case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE: 82 case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE:
82 return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE"; 83 return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE";
83 } 84 }
84 NOTREACHED(); 85 NOTREACHED();
85 return "???"; 86 return "???";
86 } 87 }
87 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
88 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 105 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
89 switch (state) { 106 switch (state) {
90 case COMMIT_STATE_IDLE: 107 case COMMIT_STATE_IDLE:
91 return "COMMIT_STATE_IDLE"; 108 return "COMMIT_STATE_IDLE";
92 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT: 109 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT:
93 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT"; 110 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT";
94 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED: 111 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED:
95 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED"; 112 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED";
96 case COMMIT_STATE_READY_TO_COMMIT: 113 case COMMIT_STATE_READY_TO_COMMIT:
97 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
135 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: 152 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
136 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; 153 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
137 case ACTION_DRAW_AND_SWAP_FORCED: 154 case ACTION_DRAW_AND_SWAP_FORCED:
138 return "ACTION_DRAW_AND_SWAP_FORCED"; 155 return "ACTION_DRAW_AND_SWAP_FORCED";
139 case ACTION_DRAW_AND_SWAP_ABORT: 156 case ACTION_DRAW_AND_SWAP_ABORT:
140 return "ACTION_DRAW_AND_SWAP_ABORT"; 157 return "ACTION_DRAW_AND_SWAP_ABORT";
141 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 158 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
142 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 159 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
143 case ACTION_PREPARE_TILES: 160 case ACTION_PREPARE_TILES:
144 return "ACTION_PREPARE_TILES"; 161 return "ACTION_PREPARE_TILES";
162 case ACTION_INVALIDATE_OUTPUT_SURFACE:
163 return "ACTION_INVALIDATE_OUTPUT_SURFACE";
145 } 164 }
146 NOTREACHED(); 165 NOTREACHED();
147 return "???"; 166 return "???";
148 } 167 }
149 168
150 scoped_refptr<base::debug::ConvertableToTraceFormat> 169 scoped_refptr<base::debug::ConvertableToTraceFormat>
151 SchedulerStateMachine::AsValue() const { 170 SchedulerStateMachine::AsValue() const {
152 scoped_refptr<base::debug::TracedValue> state = 171 scoped_refptr<base::debug::TracedValue> state =
153 new base::debug::TracedValue(); 172 new base::debug::TracedValue();
154 AsValueInto(state.get(), gfx::FrameTime::Now()); 173 AsValueInto(state.get(), gfx::FrameTime::Now());
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 282 }
264 283
265 bool SchedulerStateMachine::HasSwappedThisFrame() const { 284 bool SchedulerStateMachine::HasSwappedThisFrame() const {
266 return current_frame_number_ == last_frame_number_swap_performed_; 285 return current_frame_number_ == last_frame_number_swap_performed_;
267 } 286 }
268 287
269 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const { 288 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const {
270 return current_frame_number_ == last_frame_number_swap_requested_; 289 return current_frame_number_ == last_frame_number_swap_requested_;
271 } 290 }
272 291
292 bool SchedulerStateMachine::HasInvalidatedOutputSurfaceThisFrame() const {
293 return current_frame_number_ == last_frame_number_invalidate_output_surface_pe rformed_;
294 }
295
273 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 296 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
274 // These are all the cases where we normally cannot or do not want to draw 297 // These are all the cases where we normally cannot or do not want to draw
275 // but, if needs_redraw_ is true and we do not draw to make forward progress, 298 // but, if needs_redraw_ is true and we do not draw to make forward progress,
276 // we might deadlock with the main thread. 299 // we might deadlock with the main thread.
277 // This should be a superset of PendingActivationsShouldBeForced() since 300 // This should be a superset of PendingActivationsShouldBeForced() since
278 // activation of the pending tree is blocked by drawing of the active tree and 301 // activation of the pending tree is blocked by drawing of the active tree and
279 // the main thread might be blocked on activation of the most recent commit. 302 // the main thread might be blocked on activation of the most recent commit.
280 if (PendingActivationsShouldBeForced()) 303 if (PendingActivationsShouldBeForced())
281 return true; 304 return true;
282 305
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 // are initializing the output surface. 350 // are initializing the output surface.
328 if (active_tree_needs_first_draw_ || has_pending_tree_) 351 if (active_tree_needs_first_draw_ || has_pending_tree_)
329 return false; 352 return false;
330 353
331 // We need to create the output surface if we don't have one and we haven't 354 // We need to create the output surface if we don't have one and we haven't
332 // started creating one yet. 355 // started creating one yet.
333 return output_surface_state_ == OUTPUT_SURFACE_LOST; 356 return output_surface_state_ == OUTPUT_SURFACE_LOST;
334 } 357 }
335 358
336 bool SchedulerStateMachine::ShouldDraw() const { 359 bool SchedulerStateMachine::ShouldDraw() const {
360 // In the synchronous compositor mode, draws are initiated by the output
361 // surface only.
362 if (settings_.using_synchronous_renderer_compositor &&
363 !output_surface_did_request_draw_)
364 return false;
365
337 // If we need to abort draws, we should do so ASAP since the draw could 366 // If we need to abort draws, we should do so ASAP since the draw could
338 // be blocking other important actions (like output surface initialization), 367 // be blocking other important actions (like output surface initialization),
339 // from occuring. If we are waiting for the first draw, then perfom the 368 // from occuring. If we are waiting for the first draw, then perfom the
340 // aborted draw to keep things moving. If we are not waiting for the first 369 // aborted draw to keep things moving. If we are not waiting for the first
341 // draw however, we don't want to abort for no reason. 370 // draw however, we don't want to abort for no reason.
342 if (PendingDrawsShouldBeAborted()) 371 if (PendingDrawsShouldBeAborted())
343 return active_tree_needs_first_draw_; 372 return active_tree_needs_first_draw_;
344 373
345 // If a commit has occurred after the animate call, we need to call animate 374 // If a commit has occurred after the animate call, we need to call animate
346 // again before we should draw. 375 // again before we should draw.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 } 511 }
483 512
484 bool SchedulerStateMachine::ShouldPrepareTiles() const { 513 bool SchedulerStateMachine::ShouldPrepareTiles() const {
485 // PrepareTiles only really needs to be called immediately after commit 514 // PrepareTiles only really needs to be called immediately after commit
486 // and then periodically after that. Use a funnel to make sure we average 515 // and then periodically after that. Use a funnel to make sure we average
487 // one PrepareTiles per BeginImplFrame in the long run. 516 // one PrepareTiles per BeginImplFrame in the long run.
488 if (prepare_tiles_funnel_ > 0) 517 if (prepare_tiles_funnel_ > 0)
489 return false; 518 return false;
490 519
491 // Limiting to once per-frame is not enough, since we only want to 520 // Limiting to once per-frame is not enough, since we only want to
492 // prepare tiles _after_ draws. Polling for draw triggers and 521 // prepare tiles _after_ draws.
493 // begin-frame are mutually exclusive, so we limit to these two cases. 522 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
494 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
495 !inside_poll_for_anticipated_draw_triggers_)
496 return false; 523 return false;
524
497 return needs_prepare_tiles_; 525 return needs_prepare_tiles_;
498 } 526 }
499 527
528 bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const {
529 // Only the synchronous compositor requires invalidations.
530 if (!settings_.using_synchronous_renderer_compositor)
531 return false;
532
533 // Invalidations are only performed inside a BeginFrame excluding deadline.
534 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
535 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
536 return false;
537
538 // Invalidate the output surface only once per frame.
539 if (HasInvalidatedOutputSurfaceThisFrame())
540 return false;
541
542 return needs_redraw_;
543 }
544
500 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 545 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
501 if (ShouldActivatePendingTree()) 546 if (ShouldActivatePendingTree())
502 return ACTION_ACTIVATE_SYNC_TREE; 547 return ACTION_ACTIVATE_SYNC_TREE;
503 if (ShouldCommit()) 548 if (ShouldCommit())
504 return ACTION_COMMIT; 549 return ACTION_COMMIT;
505 if (ShouldAnimate()) 550 if (ShouldAnimate())
506 return ACTION_ANIMATE; 551 return ACTION_ANIMATE;
507 if (ShouldDraw()) { 552 if (ShouldDraw()) {
508 if (PendingDrawsShouldBeAborted()) 553 if (PendingDrawsShouldBeAborted())
509 return ACTION_DRAW_AND_SWAP_ABORT; 554 return ACTION_DRAW_AND_SWAP_ABORT;
510 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 555 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
511 return ACTION_DRAW_AND_SWAP_FORCED; 556 return ACTION_DRAW_AND_SWAP_FORCED;
512 else 557 else
513 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; 558 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
514 } 559 }
515 if (ShouldPrepareTiles()) 560 if (ShouldPrepareTiles())
516 return ACTION_PREPARE_TILES; 561 return ACTION_PREPARE_TILES;
517 if (ShouldSendBeginMainFrame()) 562 if (ShouldSendBeginMainFrame())
518 return ACTION_SEND_BEGIN_MAIN_FRAME; 563 return ACTION_SEND_BEGIN_MAIN_FRAME;
564 if (ShouldInvalidateOutputSurface())
565 return ACTION_INVALIDATE_OUTPUT_SURFACE;
519 if (ShouldBeginOutputSurfaceCreation()) 566 if (ShouldBeginOutputSurfaceCreation())
520 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 567 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
521 return ACTION_NONE; 568 return ACTION_NONE;
522 } 569 }
523 570
524 void SchedulerStateMachine::UpdateState(Action action) { 571 void SchedulerStateMachine::UpdateState(Action action) {
525 switch (action) { 572 switch (action) {
526 case ACTION_NONE: 573 case ACTION_NONE:
527 return; 574 return;
528 575
(...skipping 21 matching lines...) Expand all
550 return; 597 return;
551 598
552 case ACTION_COMMIT: { 599 case ACTION_COMMIT: {
553 bool commit_was_aborted = false; 600 bool commit_was_aborted = false;
554 UpdateStateOnCommit(commit_was_aborted); 601 UpdateStateOnCommit(commit_was_aborted);
555 return; 602 return;
556 } 603 }
557 604
558 case ACTION_DRAW_AND_SWAP_FORCED: 605 case ACTION_DRAW_AND_SWAP_FORCED:
559 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { 606 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
607 // Synchronous compositor only draws when requested.
608 DCHECK_IMPLIES(settings_.using_synchronous_renderer_compositor,
609 output_surface_did_request_draw_);
560 bool did_request_swap = true; 610 bool did_request_swap = true;
561 UpdateStateOnDraw(did_request_swap); 611 UpdateStateOnDraw(did_request_swap);
562 return; 612 return;
563 } 613 }
564 614
565 case ACTION_DRAW_AND_SWAP_ABORT: { 615 case ACTION_DRAW_AND_SWAP_ABORT: {
566 bool did_request_swap = false; 616 bool did_request_swap = false;
567 UpdateStateOnDraw(did_request_swap); 617 UpdateStateOnDraw(did_request_swap);
568 return; 618 return;
569 } 619 }
570 620
571 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 621 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
572 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 622 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
573 output_surface_state_ = OUTPUT_SURFACE_CREATING; 623 output_surface_state_ = OUTPUT_SURFACE_CREATING;
574 624
575 // The following DCHECKs make sure we are in the proper quiescent state. 625 // The following DCHECKs make sure we are in the proper quiescent state.
576 // The pipeline should be flushed entirely before we start output 626 // The pipeline should be flushed entirely before we start output
577 // surface creation to avoid complicated corner cases. 627 // surface creation to avoid complicated corner cases.
578 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 628 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
579 DCHECK(!has_pending_tree_); 629 DCHECK(!has_pending_tree_);
580 DCHECK(!active_tree_needs_first_draw_); 630 DCHECK(!active_tree_needs_first_draw_);
581 return; 631 return;
582 632
583 case ACTION_PREPARE_TILES: 633 case ACTION_PREPARE_TILES:
584 UpdateStateOnPrepareTiles(); 634 UpdateStateOnPrepareTiles();
585 return; 635 return;
636
637 case ACTION_INVALIDATE_OUTPUT_SURFACE:
638 last_frame_number_invalidate_output_surface_performed_ = current_frame_num ber_;
639 return;
586 } 640 }
587 } 641 }
588 642
589 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { 643 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) {
590 commit_count_++; 644 commit_count_++;
591 645
592 if (!commit_was_aborted && HasAnimatedThisFrame()) 646 if (!commit_was_aborted && HasAnimatedThisFrame())
593 did_commit_after_animating_ = true; 647 did_commit_after_animating_ = true;
594 648
595 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { 649 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 715
662 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { 716 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) {
663 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 717 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
664 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 718 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
665 719
666 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) 720 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW)
667 commit_state_ = COMMIT_STATE_IDLE; 721 commit_state_ = COMMIT_STATE_IDLE;
668 722
669 needs_redraw_ = false; 723 needs_redraw_ = false;
670 active_tree_needs_first_draw_ = false; 724 active_tree_needs_first_draw_ = false;
725 output_surface_did_request_draw_ = false;
671 726
672 if (did_request_swap) 727 if (did_request_swap)
673 last_frame_number_swap_requested_ = current_frame_number_; 728 last_frame_number_swap_requested_ = current_frame_number_;
674 } 729 }
675 730
676 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { 731 void SchedulerStateMachine::UpdateStateOnPrepareTiles() {
677 needs_prepare_tiles_ = false; 732 needs_prepare_tiles_ = false;
678 } 733 }
679 734
680 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 735 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
681 TRACE_EVENT_INSTANT0("cc", 736 TRACE_EVENT_INSTANT0("cc",
682 "Scheduler: SkipNextBeginMainFrameToReduceLatency", 737 "Scheduler: SkipNextBeginMainFrameToReduceLatency",
683 TRACE_EVENT_SCOPE_THREAD); 738 TRACE_EVENT_SCOPE_THREAD);
684 skip_next_begin_main_frame_to_reduce_latency_ = true; 739 skip_next_begin_main_frame_to_reduce_latency_ = true;
685 } 740 }
686 741
687 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { 742 bool SchedulerStateMachine::BeginFrameNeededForChildren() const {
688 if (HasInitializedOutputSurface()) 743 if (HasInitializedOutputSurface())
689 return children_need_begin_frames_; 744 return children_need_begin_frames_;
690 745
691 return false; 746 return false;
692 } 747 }
693 748
694 bool SchedulerStateMachine::BeginFrameNeeded() const { 749 bool SchedulerStateMachine::BeginFrameNeeded() const {
695 if (SupportsProactiveBeginFrame()) { 750 return (BeginFrameNeededToAnimateOrDraw() ||
696 return (BeginFrameNeededToAnimateOrDraw() || 751 BeginFrameNeededForChildren() ||
697 BeginFrameNeededForChildren() || 752 ProactiveBeginFrameWanted());
698 ProactiveBeginFrameWanted());
699 }
700
701 // Proactive BeginFrames are bad for the synchronous compositor because we
702 // have to draw when we get the BeginFrame and could end up drawing many
703 // duplicate frames if our new frame isn't ready in time.
704 // To poll for state with the synchronous compositor without having to draw,
705 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
706 // Synchronous compositor doesn't have a browser.
707 DCHECK(!children_need_begin_frames_);
708 return BeginFrameNeededToAnimateOrDraw();
709 }
710
711 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
712 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
713 // ProactiveBeginFrameWanted when we are using the synchronous
714 // compositor.
715 if (!SupportsProactiveBeginFrame()) {
716 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
717 }
718
719 // Non synchronous compositors should rely on
720 // ProactiveBeginFrameWanted to poll for state instead.
721 return false;
722 }
723
724 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll
725 // for changes in it's draw state so it can request a BeginFrame when it's
726 // actually ready.
727 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
728 // It is undesirable to proactively request BeginFrames if we are
729 // using a synchronous compositor because we *must* draw for every
730 // BeginFrame, which could cause duplicate draws.
731 return !settings_.using_synchronous_renderer_compositor;
732 } 753 }
733 754
734 void SchedulerStateMachine::SetChildrenNeedBeginFrames( 755 void SchedulerStateMachine::SetChildrenNeedBeginFrames(
735 bool children_need_begin_frames) { 756 bool children_need_begin_frames) {
736 DCHECK(settings_.forward_begin_frames_to_children); 757 DCHECK(settings_.forward_begin_frames_to_children);
737 children_need_begin_frames_ = children_need_begin_frames; 758 children_need_begin_frames_ = children_need_begin_frames;
738 } 759 }
739 760
740 // These are the cases where we definitely (or almost definitely) have a 761 // These are the cases where we definitely (or almost definitely) have a
741 // new frame to animate and/or draw and can draw. 762 // new frame to animate and/or draw and can draw.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 } 836 }
816 837
817 void SchedulerStateMachine::OnBeginImplFrameIdle() { 838 void SchedulerStateMachine::OnBeginImplFrameIdle() {
818 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 839 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
819 << AsValue()->ToString(); 840 << AsValue()->ToString();
820 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; 841 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
821 } 842 }
822 843
823 SchedulerStateMachine::BeginImplFrameDeadlineMode 844 SchedulerStateMachine::BeginImplFrameDeadlineMode
824 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 845 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
825 if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 846 if (settings_.using_synchronous_renderer_compositor &&
826 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 847 output_surface_did_request_draw_) {
848 // If the synchronous compositor wants to draw now or if we know that the
849 // synchronous compositor won't draw trigger an immediate deadline.
850 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_SYNCHRONOUS;
851 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
852 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE_ASYNCHRONOUS;
827 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { 853 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
828 // We have an animation or fast input path on the impl thread that wants 854 // We have an animation or fast input path on the impl thread that wants
829 // to draw, so don't wait too long for a new active tree. 855 // to draw, so don't wait too long for a new active tree.
830 // If we are swap throttled we should wait until we are unblocked. 856 // If we are swap throttled we should wait until we are unblocked.
831 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 857 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
832 } else { 858 } else {
833 // The impl thread doesn't have anything it wants to draw and we are just 859 // The impl thread doesn't have anything it wants to draw and we are just
834 // waiting for a new active tree or we are swap throttled. In short we are 860 // waiting for a new active tree or we are swap throttled. In short we are
835 // blocked. 861 // blocked.
836 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 862 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
837 } 863 }
838 } 864 }
839 865
840 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 866 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
841 const { 867 const {
842 // TODO(brianderson): This should take into account multiple commit sources. 868 // TODO(brianderson): This should take into account multiple commit sources.
869
870 // Set an immediate asynchronous deadline for the synchronous compositor.
871 // If the output surface was invalidated, then the synchronous compositor will
872 // cause the deadline to be rescheduled on OutputSurfaceDidRequestDraw.
873 // If the output surface was not invalidated (i.e. needs_redraw_ is false)
874 // then the deadline will pass but drawing will not happen.
875 if (settings_.using_synchronous_renderer_compositor)
876 return true;
843 877
844 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 878 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
845 return false; 879 return false;
846 880
847 // If we've lost the output surface, end the current BeginImplFrame ASAP 881 // If we've lost the output surface, end the current BeginImplFrame ASAP
848 // so we can start creating the next output surface. 882 // so we can start creating the next output surface.
849 if (output_surface_state_ == OUTPUT_SURFACE_LOST) 883 if (output_surface_state_ == OUTPUT_SURFACE_LOST)
850 return true; 884 return true;
851 885
852 // SwapAck throttle the deadline since we wont draw and swap anyway. 886 // SwapAck throttle the deadline since we wont draw and swap anyway.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // which case the main thread is in a high latency mode. 947 // which case the main thread is in a high latency mode.
914 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && 948 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) &&
915 !HasSentBeginMainFrameThisFrame(); 949 !HasSentBeginMainFrameThisFrame();
916 } 950 }
917 951
918 // If the active tree needs its first draw in any other state, we know the 952 // If the active tree needs its first draw in any other state, we know the
919 // main thread is in a high latency mode. 953 // main thread is in a high latency mode.
920 return active_tree_needs_first_draw_; 954 return active_tree_needs_first_draw_;
921 } 955 }
922 956
923 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
924 AdvanceCurrentFrameNumber();
925 inside_poll_for_anticipated_draw_triggers_ = true;
926 }
927
928 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
929 inside_poll_for_anticipated_draw_triggers_ = false;
930 }
931
932 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 957 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
933 958
934 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 959 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
935 960
936 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 961 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
937 962
963 void SchedulerStateMachine::OutputSurfaceDidRequestDraw() {
964 output_surface_did_request_draw_ = true;
965 }
966
938 void SchedulerStateMachine::SetNeedsAnimate() { 967 void SchedulerStateMachine::SetNeedsAnimate() {
939 needs_animate_ = true; 968 needs_animate_ = true;
940 } 969 }
941 970
942 void SchedulerStateMachine::SetNeedsPrepareTiles() { 971 void SchedulerStateMachine::SetNeedsPrepareTiles() {
943 if (!needs_prepare_tiles_) { 972 if (!needs_prepare_tiles_) {
944 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); 973 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
945 needs_prepare_tiles_ = true; 974 needs_prepare_tiles_ = true;
946 } 975 }
947 } 976 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 static_cast<int>(begin_impl_frame_state_), 1124 static_cast<int>(begin_impl_frame_state_),
1096 static_cast<int>(commit_state_), 1125 static_cast<int>(commit_state_),
1097 has_pending_tree_ ? 'T' : 'F', 1126 has_pending_tree_ ? 'T' : 'F',
1098 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1127 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1099 active_tree_needs_first_draw_ ? 'T' : 'F', 1128 active_tree_needs_first_draw_ ? 'T' : 'F',
1100 max_pending_swaps_, 1129 max_pending_swaps_,
1101 pending_swaps_); 1130 pending_swaps_);
1102 } 1131 }
1103 1132
1104 } // namespace cc 1133 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698