| Index: cc/scheduler/scheduler_state_machine.cc
|
| diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
|
| index 91ae485850381b5ce41b3eb509a11d06deb5ba09..837a5afdd1e89117be61523f0e0ed2ed1439ff04 100644
|
| --- a/cc/scheduler/scheduler_state_machine.cc
|
| +++ b/cc/scheduler/scheduler_state_machine.cc
|
| @@ -10,6 +10,7 @@
|
| #include "base/trace_event/trace_event.h"
|
| #include "base/trace_event/trace_event_argument.h"
|
| #include "base/values.h"
|
| +#include "cc/output/begin_frame_args.h"
|
|
|
| namespace cc {
|
|
|
| @@ -24,6 +25,16 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
|
| begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
|
| begin_main_frame_state_(BEGIN_MAIN_FRAME_STATE_IDLE),
|
| forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
|
| + begin_frame_source_id_(0),
|
| + begin_frame_sequence_number_(BeginFrameArgs::kInvalidFrameNumber),
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_(
|
| + BeginFrameArgs::kInvalidFrameNumber),
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_(
|
| + BeginFrameArgs::kInvalidFrameNumber),
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_(
|
| + BeginFrameArgs::kInvalidFrameNumber),
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_(
|
| + BeginFrameArgs::kInvalidFrameNumber),
|
| commit_count_(0),
|
| current_frame_number_(0),
|
| last_frame_number_submit_performed_(-1),
|
| @@ -214,6 +225,18 @@ void SchedulerStateMachine::AsValueInto(
|
| last_frame_number_draw_performed_);
|
| state->SetInteger("last_frame_number_begin_main_frame_sent",
|
| last_frame_number_begin_main_frame_sent_);
|
| + state->SetInteger("begin_frame_source_id", begin_frame_source_id_);
|
| + state->SetInteger("begin_frame_sequence_number",
|
| + begin_frame_sequence_number_);
|
| + state->SetInteger("last_begin_frame_sequence_number_begin_main_frame_sent",
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_);
|
| + state->SetInteger("last_begin_frame_sequence_number_pending_tree_was_fresh",
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_);
|
| + state->SetInteger("last_begin_frame_sequence_number_active_tree_was_fresh",
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_);
|
| + state->SetInteger(
|
| + "last_begin_frame_sequence_number_compositor_frame_was_fresh",
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_);
|
| state->SetBoolean("funnel: draw_funnel", draw_funnel_);
|
| state->SetBoolean("funnel: send_begin_main_frame_funnel",
|
| send_begin_main_frame_funnel_);
|
| @@ -574,6 +597,8 @@ void SchedulerStateMachine::WillSendBeginMainFrame() {
|
| needs_begin_main_frame_ = false;
|
| send_begin_main_frame_funnel_ = true;
|
| last_frame_number_begin_main_frame_sent_ = current_frame_number_;
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_ =
|
| + begin_frame_sequence_number_;
|
| }
|
|
|
| void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
|
| @@ -584,10 +609,29 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
|
| last_commit_had_no_updates_ = commit_has_no_updates;
|
| begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE;
|
|
|
| - if (!commit_has_no_updates) {
|
| - // Pending tree only exists if commit had updates.
|
| + if (commit_has_no_updates) {
|
| + // Pending tree might still exist from prior commit.
|
| + if (has_pending_tree_) {
|
| + DCHECK(settings_.main_frame_before_activation_enabled);
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_ =
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_;
|
| + } else {
|
| + if (last_begin_frame_sequence_number_compositor_frame_was_fresh_ ==
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_) {
|
| + // Assuming that SetNeedsRedraw() is only called at the beginning of
|
| + // a BeginFrame, we can update the compositor frame freshness.
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_ =
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_;
|
| + }
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_ =
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_;
|
| + }
|
| + } else {
|
| + // We have a new pending tree.
|
| has_pending_tree_ = true;
|
| pending_tree_is_ready_for_activation_ = false;
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_ =
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_;
|
| wait_for_ready_to_draw_ = settings_.commit_to_active_tree;
|
| }
|
|
|
| @@ -619,6 +663,8 @@ void SchedulerStateMachine::WillActivate() {
|
| pending_tree_is_ready_for_activation_ = false;
|
| active_tree_needs_first_draw_ = true;
|
| needs_redraw_ = true;
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_ =
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_;
|
| }
|
|
|
| void SchedulerStateMachine::WillDrawInternal() {
|
| @@ -650,9 +696,17 @@ void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) {
|
| NOTREACHED() << "Invalid return DrawResult:" << draw_result;
|
| break;
|
| case DRAW_ABORTED_DRAINING_PIPELINE:
|
| + consecutive_checkerboard_animations_ = 0;
|
| + forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
|
| + break;
|
| case DRAW_SUCCESS:
|
| consecutive_checkerboard_animations_ = 0;
|
| forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
|
| + // The draw either didn't have damage or had damage and submitted a
|
| + // CompositorFrame. In either case, the compositor frame freshness should
|
| + // be updated to match the active tree.
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_ =
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_;
|
| break;
|
| case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS:
|
| DCHECK(!did_submit_in_last_frame_);
|
| @@ -815,7 +869,65 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
|
| return false;
|
| }
|
|
|
| -void SchedulerStateMachine::OnBeginImplFrame() {
|
| +void SchedulerStateMachine::OnBeginFrameDroppedNotObserving(
|
| + uint32_t source_id,
|
| + uint64_t sequence_number) {
|
| + DCHECK(!BeginFrameNeeded());
|
| + DCHECK_EQ(BEGIN_IMPL_FRAME_STATE_IDLE, begin_impl_frame_state_);
|
| +
|
| + // Confirms the dropped BeginFrame, since we don't have updates.
|
| + UpdateBeginFrameSequenceNumbersForBeginFrame(source_id, sequence_number);
|
| + UpdateBeginFrameSequenceNumbersForBeginFrameDeadline();
|
| +}
|
| +
|
| +void SchedulerStateMachine::UpdateBeginFrameSequenceNumbersForBeginFrame(
|
| + uint32_t source_id,
|
| + uint64_t sequence_number) {
|
| + if (source_id != begin_frame_source_id_) {
|
| + begin_frame_source_id_ = source_id;
|
| + begin_frame_sequence_number_ = sequence_number;
|
| +
|
| + // Reset freshness sequence numbers.
|
| + last_begin_frame_sequence_number_begin_main_frame_sent_ =
|
| + BeginFrameArgs::kInvalidFrameNumber;
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_ =
|
| + BeginFrameArgs::kInvalidFrameNumber;
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_ =
|
| + BeginFrameArgs::kInvalidFrameNumber;
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_ =
|
| + BeginFrameArgs::kInvalidFrameNumber;
|
| + } else {
|
| + DCHECK_GT(sequence_number, begin_frame_sequence_number_);
|
| + begin_frame_sequence_number_ = sequence_number;
|
| + }
|
| +}
|
| +
|
| +void SchedulerStateMachine::
|
| + UpdateBeginFrameSequenceNumbersForBeginFrameDeadline() {
|
| + // Update frame numbers for freshness in case no updates were necessary.
|
| + if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE ||
|
| + needs_begin_main_frame_) {
|
| + return;
|
| + }
|
| +
|
| + if (has_pending_tree_) {
|
| + last_begin_frame_sequence_number_pending_tree_was_fresh_ =
|
| + begin_frame_sequence_number_;
|
| + return;
|
| + }
|
| +
|
| + last_begin_frame_sequence_number_active_tree_was_fresh_ =
|
| + begin_frame_sequence_number_;
|
| +
|
| + if (!needs_redraw_)
|
| + last_begin_frame_sequence_number_compositor_frame_was_fresh_ =
|
| + begin_frame_sequence_number_;
|
| +}
|
| +
|
| +void SchedulerStateMachine::OnBeginImplFrame(uint32_t source_id,
|
| + uint64_t sequence_number) {
|
| + UpdateBeginFrameSequenceNumbersForBeginFrame(source_id, sequence_number);
|
| +
|
| begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
|
| current_frame_number_++;
|
|
|
| @@ -844,6 +956,9 @@ void SchedulerStateMachine::OnBeginImplFrameDeadline() {
|
| if (prepare_tiles_funnel_ > 0)
|
| prepare_tiles_funnel_--;
|
| }
|
| +
|
| + if (!settings_.using_synchronous_renderer_compositor)
|
| + UpdateBeginFrameSequenceNumbersForBeginFrameDeadline();
|
| }
|
|
|
| void SchedulerStateMachine::OnBeginImplFrameIdle() {
|
| @@ -860,6 +975,12 @@ void SchedulerStateMachine::OnBeginImplFrameIdle() {
|
| // funnels so that we don't perform any actions that we shouldn't.
|
| if (!BeginFrameNeeded())
|
| send_begin_main_frame_funnel_ = true;
|
| +
|
| + // Synchronous compositor finishes BeginFrames before triggering their
|
| + // deadline. Therefore, we update sequence numbers when becoming idle, before
|
| + // the Scheduler sends its BeginFrameAck.
|
| + if (settings_.using_synchronous_renderer_compositor)
|
| + UpdateBeginFrameSequenceNumbersForBeginFrameDeadline();
|
| }
|
|
|
| SchedulerStateMachine::BeginImplFrameDeadlineMode
|
|
|