diff options
author | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-12 21:58:22 +0000 |
---|---|---|
committer | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-12 21:58:22 +0000 |
commit | 0c7a561ae2ea208ba1103d9cdab6c3ee4264c8b7 (patch) | |
tree | c93b244a447ce963d68c22175047ed7aa0777304 /cc | |
parent | 718e922a6d41e4465a11ac9536240878394c1626 (diff) | |
download | chromium_src-0c7a561ae2ea208ba1103d9cdab6c3ee4264c8b7.zip chromium_src-0c7a561ae2ea208ba1103d9cdab6c3ee4264c8b7.tar.gz chromium_src-0c7a561ae2ea208ba1103d9cdab6c3ee4264c8b7.tar.bz2 |
cc: Allow sending BeginMainFrame before draw or activation
BeginMainFrame before draw:
Enabled by default because of concurrency benefits.
When main thread painting, this will block the main thread from
finishing the commit until the active tree has been drawn.
When impl side painting, this does not block the main thread.
The following flag will disable sending BeginMainFrame to the
main thread before we draw the previous commit:
--disable-main-frame-before-draw
BeginMainFrame before activation:
Disabled by default because of latency concerns.
This applies only when impl-side-painting is enabled and will
cause the main thread to block finishing the commit until the
pending tree is activated.
The following flags control whether BeginMainFrame is sent to
the main thread before or after the previous commit has
activated:
--enable-main-frame-before-activation
--disable-main-frame-before-activation
BUG=293941
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=256454
Review URL: https://codereview.chromium.org/23907006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@256669 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/base/switches.cc | 13 | ||||
-rw-r--r-- | cc/base/switches.h | 3 | ||||
-rw-r--r-- | cc/scheduler/scheduler.cc | 3 | ||||
-rw-r--r-- | cc/scheduler/scheduler_settings.cc | 4 | ||||
-rw-r--r-- | cc/scheduler/scheduler_settings.h | 2 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.cc | 78 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.h | 7 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine_unittest.cc | 268 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_animation.cc | 22 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_context.cc | 6 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.h | 2 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 8 |
13 files changed, 309 insertions, 109 deletions
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index 4cff4d2..0731598 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc @@ -15,6 +15,19 @@ const char kDisableThreadedAnimation[] = "disable-threaded-animation"; const char kDisableCompositedAntialiasing[] = "disable-composited-antialiasing"; +// Disables sending the next BeginMainFrame before the previous commit has +// drawn. +const char kDisableMainFrameBeforeDraw[] = "disable-main-frame-before-draw"; + +// Disables sending the next BeginMainFrame before the previous commit +// activates. Overrides the kEnableMainFrameBeforeActivation flag. +const char kDisableMainFrameBeforeActivation[] = + "disable-main-frame-before-activation"; + +// Enables sending the next BeginMainFrame before the previous commit activates. +const char kEnableMainFrameBeforeActivation[] = + "enable-main-frame-before-activation"; + const char kEnableTopControlsPositionCalculation[] = "enable-top-controls-position-calculation"; diff --git a/cc/base/switches.h b/cc/base/switches.h index 8cb043f..b8b2243 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h @@ -18,6 +18,9 @@ namespace switches { // Switches for the renderer compositor only. CC_EXPORT extern const char kDisableThreadedAnimation[]; CC_EXPORT extern const char kDisableCompositedAntialiasing[]; +CC_EXPORT extern const char kDisableMainFrameBeforeDraw[]; +CC_EXPORT extern const char kDisableMainFrameBeforeActivation[]; +CC_EXPORT extern const char kEnableMainFrameBeforeActivation[]; CC_EXPORT extern const char kEnableTopControlsPositionCalculation[]; CC_EXPORT extern const char kJankInsteadOfCheckerboard[]; CC_EXPORT extern const char kTopControlsHeight[]; diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 741b9c8..ef4ba8f 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -27,6 +27,9 @@ Scheduler::Scheduler(SchedulerClient* client, weak_factory_(this) { DCHECK(client_); DCHECK(!state_machine_.BeginImplFrameNeeded()); + if (settings_.main_frame_before_activation_enabled) { + DCHECK(settings_.main_frame_before_draw_enabled); + } } Scheduler::~Scheduler() {} diff --git a/cc/scheduler/scheduler_settings.cc b/cc/scheduler/scheduler_settings.cc index 086028e..808a9fa 100644 --- a/cc/scheduler/scheduler_settings.cc +++ b/cc/scheduler/scheduler_settings.cc @@ -7,7 +7,9 @@ namespace cc { SchedulerSettings::SchedulerSettings() - : impl_side_painting(false), + : main_frame_before_draw_enabled(true), + main_frame_before_activation_enabled(false), + impl_side_painting(false), timeout_and_draw_when_animation_checkerboards(true), maximum_number_of_failed_draws_before_draw_is_forced_(3), using_synchronous_renderer_compositor(false), diff --git a/cc/scheduler/scheduler_settings.h b/cc/scheduler/scheduler_settings.h index 66d276c..4b2f664 100644 --- a/cc/scheduler/scheduler_settings.h +++ b/cc/scheduler/scheduler_settings.h @@ -14,6 +14,8 @@ class CC_EXPORT SchedulerSettings { SchedulerSettings(); ~SchedulerSettings(); + bool main_frame_before_draw_enabled; + bool main_frame_before_activation_enabled; bool impl_side_painting; bool timeout_and_draw_when_animation_checkerboards; int maximum_number_of_failed_draws_before_draw_is_forced_; diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index 7577fb4..2bbf256 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc @@ -90,6 +90,8 @@ const char* SchedulerStateMachine::CommitStateToString(CommitState state) { return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED"; case COMMIT_STATE_READY_TO_COMMIT: return "COMMIT_STATE_READY_TO_COMMIT"; + case COMMIT_STATE_WAITING_FOR_ACTIVATION: + return "COMMIT_STATE_WAITING_FOR_ACTIVATION"; case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; } @@ -374,10 +376,8 @@ bool SchedulerStateMachine::ShouldDraw() const { return false; // Draw immediately for readbacks to unblock the main thread quickly. - if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) return true; - } // If we need to abort draws, we should do so ASAP since the draw could // be blocking other important actions (like output surface initialization), @@ -397,10 +397,8 @@ bool SchedulerStateMachine::ShouldDraw() const { return false; // Only handle forced redraws due to timeouts on the regular deadline. - if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) return true; - } return needs_redraw_; } @@ -465,9 +463,12 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { if (commit_state_ != COMMIT_STATE_IDLE) return false; - // We can't accept a commit if we have a pending tree. - if (has_pending_tree_) + // Don't send BeginMainFrame early if we are prioritizing the active tree + // because of smoothness_takes_priority. + if (smoothness_takes_priority_ && + (has_pending_tree_ || active_tree_needs_first_draw_)) { return false; + } // We want to handle readback commits immediately to unblock the main thread. // Note: This BeginMainFrame will correspond to the replacement commit that @@ -514,7 +515,20 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { } bool SchedulerStateMachine::ShouldCommit() const { - return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; + if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) + return false; + + // We must not finish the commit until the pending tree is free. + if (has_pending_tree_) { + DCHECK(settings_.main_frame_before_activation_enabled); + return false; + } + + // Prioritize drawing the previous commit before finishing the next commit. + if (active_tree_needs_first_draw_) + return false; + + return true; } bool SchedulerStateMachine::ShouldManageTiles() const { @@ -588,7 +602,10 @@ void SchedulerStateMachine::UpdateState(Action action) { return; case ACTION_SEND_BEGIN_MAIN_FRAME: - DCHECK(!has_pending_tree_); + DCHECK(!has_pending_tree_ || + settings_.main_frame_before_activation_enabled); + DCHECK(!active_tree_needs_first_draw_ || + settings_.main_frame_before_draw_enabled); DCHECK(visible_ || readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME); commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; @@ -645,6 +662,16 @@ void SchedulerStateMachine::UpdateState(Action action) { void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { commit_count_++; + if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { + commit_state_ = COMMIT_STATE_IDLE; + } else if (settings_.main_frame_before_draw_enabled) { + commit_state_ = settings_.impl_side_painting + ? COMMIT_STATE_WAITING_FOR_ACTIVATION + : COMMIT_STATE_IDLE; + } else { + commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; + } + // If we are impl-side-painting but the commit was aborted, then we behave // mostly as if we are not impl-side-painting since there is no pending tree. has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; @@ -690,18 +717,6 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { } } - // Update the commit state. We expect and wait for a draw if the commit - // was not aborted or if we are in a readback or forced draw. - if (!commit_was_aborted) { - DCHECK(commit_state_ == COMMIT_STATE_READY_TO_COMMIT); - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; - } else if (readback_state_ != READBACK_STATE_IDLE || - forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) { - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; - } else { - commit_state_ = COMMIT_STATE_IDLE; - } - // Update state if we have a new active tree to draw, or if the active tree // was unchanged but we need to do a readback or forced draw. if (!has_pending_tree_ && @@ -727,6 +742,9 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { } void SchedulerStateMachine::UpdateStateOnActivation() { + if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) + commit_state_ = COMMIT_STATE_IDLE; + if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) output_surface_state_ = OUTPUT_SURFACE_ACTIVE; @@ -750,8 +768,7 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { << *AsValue(); if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { - // The draw correspons to a readback commit. - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + // The draw corresponds to a readback commit. // We are blocking commits from the main thread until after this draw, so // we should not have a pending tree. DCHECK(!has_pending_tree_); @@ -760,14 +777,12 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; readback_state_ = READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT; } else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); - commit_state_ = COMMIT_STATE_IDLE; forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; - } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW && - !has_pending_tree_) { - commit_state_ = COMMIT_STATE_IDLE; } + if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) + commit_state_ = COMMIT_STATE_IDLE; + if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; @@ -962,6 +977,11 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { } bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { + // If a commit is pending before the previous commit has been drawn, we + // are definitely in a high latency mode. + if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) + return true; + // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main // thread is in a low latency mode. if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ && diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 8dbf829..40a054f 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h @@ -63,6 +63,7 @@ class CC_EXPORT SchedulerStateMachine { COMMIT_STATE_BEGIN_MAIN_FRAME_SENT, COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED, COMMIT_STATE_READY_TO_COMMIT, + COMMIT_STATE_WAITING_FOR_ACTIVATION, COMMIT_STATE_WAITING_FOR_FIRST_DRAW, }; static const char* CommitStateToString(CommitState state); @@ -100,6 +101,7 @@ class CC_EXPORT SchedulerStateMachine { commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED || commit_state_ == COMMIT_STATE_READY_TO_COMMIT; } + CommitState commit_state() const { return commit_state_; } bool RedrawPending() const { return needs_redraw_; } bool ManageTilesPending() const { return needs_manage_tiles_; } @@ -231,6 +233,9 @@ class CC_EXPORT SchedulerStateMachine { void NotifyReadyToActivate(); bool has_pending_tree() const { return has_pending_tree_; } + bool active_tree_needs_first_draw() const { + return active_tree_needs_first_draw_; + } void DidManageTiles(); void DidLoseOutputSurface(); @@ -242,8 +247,6 @@ class CC_EXPORT SchedulerStateMachine { bool SupportsProactiveBeginImplFrame() const; - CommitState commit_state() const { return commit_state_; } - protected: bool BeginImplFrameNeededToDraw() const; bool ProactiveBeginImplFrameWanted() const; diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc index 2e4a7bb..f31dabb 100644 --- a/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/cc/scheduler/scheduler_state_machine_unittest.cc @@ -11,11 +11,6 @@ EXPECT_EQ(action, state.NextAction()) << *state.AsValue(); \ if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \ action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \ - if (SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW == \ - state.CommitState() && \ - SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE != \ - state.output_surface_state()) \ - return; \ EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \ state.begin_impl_frame_state()) \ << *state.AsValue(); \ @@ -45,7 +40,8 @@ const SchedulerStateMachine::CommitState all_commit_states[] = { SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT, SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED, SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, - SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, }; + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION, + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW}; // Exposes the protected state fields of the SchedulerStateMachine for testing class StateMachine : public SchedulerStateMachine { @@ -85,7 +81,7 @@ class StateMachine : public SchedulerStateMachine { void SetNeedsForcedRedrawForTimeout(bool b) { forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; + active_tree_needs_first_draw_ = true; } bool NeedsForcedRedrawForTimeout() const { return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE; @@ -93,7 +89,7 @@ class StateMachine : public SchedulerStateMachine { void SetNeedsForcedRedrawForReadback() { readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK; - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; + active_tree_needs_first_draw_ = true; } bool NeedsForcedRedrawForReadback() const { @@ -185,6 +181,135 @@ TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { } } +// Explicitly test main_frame_before_draw_enabled = false +TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) { + SchedulerSettings scheduler_settings; + scheduler_settings.impl_side_painting = true; + scheduler_settings.main_frame_before_draw_enabled = false; + StateMachine state(scheduler_settings); + state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); + state.SetCanStart(); + state.UpdateState(state.NextAction()); + state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); + state.SetNeedsRedraw(false); + state.SetVisible(true); + state.SetCanDraw(true); + state.SetNeedsCommit(); + + EXPECT_TRUE(state.BeginImplFrameNeeded()); + + // Commit to the pending tree. + state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + + // Verify that the next commit doesn't start until the previous + // commit has been drawn. + state.SetNeedsCommit(); + state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Verify NotifyReadyToActivate unblocks activation, draw, and + // commit in that order. + state.NotifyReadyToActivate(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); + + EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly()); + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), + SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); + + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), + SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); +} + +// Explicitly test main_frame_before_activation_enabled = true +TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) { + SchedulerSettings scheduler_settings; + scheduler_settings.impl_side_painting = true; + scheduler_settings.main_frame_before_activation_enabled = true; + StateMachine state(scheduler_settings); + state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); + state.SetCanStart(); + state.UpdateState(state.NextAction()); + state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); + state.SetNeedsRedraw(false); + state.SetVisible(true); + state.SetCanDraw(true); + state.SetNeedsCommit(); + + EXPECT_TRUE(state.BeginImplFrameNeeded()); + + // Commit to the pending tree. + state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE); + + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Verify that the next commit starts while there is still a pending tree. + state.SetNeedsCommit(); + state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Verify the pending commit doesn't overwrite the pending + // tree until the pending tree has been activated. + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Verify NotifyReadyToActivate unblocks activation, draw, and + // commit in that order. + state.NotifyReadyToActivate(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly()); + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE); +} + TEST(SchedulerStateMachineTest, TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) { SchedulerSettings default_scheduler_settings; @@ -288,9 +413,11 @@ TEST(SchedulerStateMachineTest, EXPECT_TRUE(state.RedrawPending()); } -TEST(SchedulerStateMachineTest, - TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit) { +void TestFailedDrawsEventuallyForceDrawAfterNextCommit( + bool main_frame_before_draw_enabled) { SchedulerSettings scheduler_settings; + scheduler_settings.main_frame_before_draw_enabled = + main_frame_before_draw_enabled; scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1; StateMachine state(scheduler_settings); state.SetCanStart(); @@ -333,12 +460,30 @@ TEST(SchedulerStateMachineTest, // The redraw should be forced at the end of the next BeginImplFrame. state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); + if (main_frame_before_draw_enabled) { + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + } EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED); } +TEST(SchedulerStateMachineTest, + TestFailedDrawsEventuallyForceDrawAfterNextCommit) { + bool main_frame_before_draw_enabled = false; + TestFailedDrawsEventuallyForceDrawAfterNextCommit( + main_frame_before_draw_enabled); +} + +TEST(SchedulerStateMachineTest, + TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw) { + bool main_frame_before_draw_enabled = true; + TestFailedDrawsEventuallyForceDrawAfterNextCommit( + main_frame_before_draw_enabled); +} + TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { SchedulerSettings scheduler_settings; int draw_limit = 1; @@ -520,19 +665,14 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { } } - // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw or - // SetNeedsForcedRedrawForReadback have been called... except if we're - // ready to commit, in which case we expect a commit first. + // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw + // except if we're ready to commit, in which case we expect a commit first. + // SetNeedsForcedRedrawForReadback should take precedence over all and + // issue a readback. for (size_t i = 0; i < num_commit_states; ++i) { for (size_t j = 0; j < 2; ++j) { bool request_readback = j; - // Skip invalid states - if (request_readback && - (SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW != - all_commit_states[i])) - continue; - StateMachine state(default_scheduler_settings); state.SetCanStart(); state.UpdateState(state.NextAction()); @@ -549,15 +689,11 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { } SchedulerStateMachine::Action expected_action; - if (all_commit_states[i] == - SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) { + if (request_readback) { + expected_action = SchedulerStateMachine::ACTION_DRAW_AND_READBACK; + } else if (all_commit_states[i] == + SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) { expected_action = SchedulerStateMachine::ACTION_COMMIT; - } else if (request_readback) { - if (all_commit_states[i] == - SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW) - expected_action = SchedulerStateMachine::ACTION_DRAW_AND_READBACK; - else - expected_action = SchedulerStateMachine::ACTION_NONE; } else { expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE; @@ -566,13 +702,13 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { // Case 1: needs_commit=false. EXPECT_NE(state.BeginImplFrameNeeded(), request_readback) << *state.AsValue(); - EXPECT_EQ(expected_action, state.NextAction()) << *state.AsValue(); + EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue(); // Case 2: needs_commit=true. state.SetNeedsCommit(); EXPECT_NE(state.BeginImplFrameNeeded(), request_readback) << *state.AsValue(); - EXPECT_EQ(expected_action, state.NextAction()) << *state.AsValue(); + EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue(); } } } @@ -643,8 +779,6 @@ TEST(SchedulerStateMachineTest, state.UpdateState(state.NextAction()); state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); - state.SetCommitState( - SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); state.SetActiveTreeNeedsFirstDraw(true); state.SetNeedsCommit(); state.SetNeedsRedraw(true); @@ -663,9 +797,11 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } -TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { - SchedulerSettings default_scheduler_settings; - StateMachine state(default_scheduler_settings); +void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) { + SchedulerSettings scheduler_settings; + scheduler_settings.main_frame_before_draw_enabled = + main_frame_before_draw_enabled; + StateMachine state(scheduler_settings); state.SetCanStart(); state.UpdateState(state.NextAction()); state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); @@ -717,22 +853,38 @@ TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { state.begin_impl_frame_state()); EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); - // Commit and make sure we draw on next BeginImplFrame + // Finish the commit, then make sure we start the next commit immediately + // and draw on the next BeginImplFrame. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + if (main_frame_before_draw_enabled) { + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + } EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + state.OnBeginImplFrameDeadline(); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS); - - // Verify that another commit will start immediately after draw. - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + if (!main_frame_before_draw_enabled) { + EXPECT_ACTION_UPDATE_STATE( + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + } EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } +TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) { + bool main_frame_before_draw_enabled = false; + TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled); +} + +TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost_CommitBeforeDraw) { + bool main_frame_before_draw_enabled = true; + TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled); +} + TEST(SchedulerStateMachineTest, TestFullCycle) { SchedulerSettings default_scheduler_settings; StateMachine state(default_scheduler_settings); @@ -762,8 +914,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) { // Commit. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_TRUE(state.needs_redraw()); // Expect to do nothing until BeginImplFrame deadline @@ -814,8 +965,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { // First commit. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_TRUE(state.needs_redraw()); // Expect to do nothing until BeginImplFrame deadline. @@ -1105,8 +1255,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { // We will abort the draw when the output surface is lost if we are // waiting for the first draw to unblock the main thread. - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE @@ -1168,8 +1317,7 @@ TEST(SchedulerStateMachineTest, state.NotifyBeginMainFrameStarted(); state.NotifyReadyToCommit(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); // Because the output surface is missing, we expect the draw to abort. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); @@ -1228,8 +1376,6 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { state.DidLoseOutputSurface(); // Ask a forced redraw for readback and verify it ocurrs. - state.SetCommitState( - SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); state.SetNeedsForcedRedrawForReadback(); state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); @@ -1257,8 +1403,6 @@ TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); // Ask a readback and verify it occurs. - state.SetCommitState( - SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); state.SetNeedsForcedRedrawForReadback(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -1401,8 +1545,7 @@ TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) { EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); state.UpdateState(state.NextAction()); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); } @@ -1422,8 +1565,7 @@ TEST(SchedulerStateMachineTest, TestFinishCommitWhenForcedCommitInProgress) { state.NotifyReadyToCommit(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); // When the readback interrupts the normal commit, we should not get @@ -1494,8 +1636,7 @@ TEST(SchedulerStateMachineTest, TestImmediateFinishCommit) { state.CommitState()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS); @@ -1531,8 +1672,7 @@ TEST(SchedulerStateMachineTest, TestImmediateFinishCommitDuringCommit) { state.CommitState()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS); @@ -1566,8 +1706,7 @@ TEST(SchedulerStateMachineTest, ImmediateBeginMainFrameAbortedWhileInvisible) { state.CommitState()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS); @@ -1608,8 +1747,7 @@ TEST(SchedulerStateMachineTest, ImmediateFinishCommitWhileCantDraw) { state.CommitState()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); - EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, - state.CommitState()); + EXPECT_TRUE(state.active_tree_needs_first_draw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK); state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS); diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index 7a9b63f..aeeb4f5 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc @@ -829,33 +829,43 @@ MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate); class LayerTreeHostAnimationTestCancelAnimateCommit : public LayerTreeHostAnimationTest { public: - LayerTreeHostAnimationTestCancelAnimateCommit() : num_animate_calls_(0) {} + LayerTreeHostAnimationTestCancelAnimateCommit() + : num_animate_calls_(0), num_commit_calls_(0), num_draw_calls_(0) {} virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } virtual void Animate(base::TimeTicks) OVERRIDE { + num_animate_calls_++; // No-op animate will cancel the commit. - if (++num_animate_calls_ == 2) { + if (layer_tree_host()->source_frame_number() == 1) { EndTest(); return; } layer_tree_host()->SetNeedsAnimate(); } - virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE { - if (num_animate_calls_ > 1) + virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { + num_commit_calls_++; + if (impl->active_tree()->source_frame_number() > 1) FAIL() << "Commit should have been canceled."; } virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { - if (num_animate_calls_ > 1) + num_draw_calls_++; + if (impl->active_tree()->source_frame_number() > 1) FAIL() << "Draw should have been canceled."; } - virtual void AfterTest() OVERRIDE { EXPECT_EQ(2, num_animate_calls_); } + virtual void AfterTest() OVERRIDE { + EXPECT_EQ(2, num_animate_calls_); + EXPECT_EQ(1, num_commit_calls_); + EXPECT_EQ(1, num_draw_calls_); + } private: int num_animate_calls_; + int num_commit_calls_; + int num_draw_calls_; FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> content_; }; diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index baf2b2d..925eda4 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -1126,10 +1126,8 @@ class LayerTreeHostContextTestDontUseLostResources // This will get called twice: // First when we create the initial output surface... if (layer_tree_host()->source_frame_number() > 0) { - // ... and then again after we forced the context to be lost on the third - // frame. Verify this assumption here. + // ... and then again after we forced the context to be lost. lost_context_ = true; - EXPECT_EQ(layer_tree_host()->source_frame_number(), 3); } return LayerTreeHostContextTest::CreateFakeOutputSurface(fallback); } @@ -1137,7 +1135,7 @@ class LayerTreeHostContextTestDontUseLostResources virtual void DidCommitAndDrawFrame() OVERRIDE { ASSERT_TRUE(layer_tree_host()->hud_layer()); // End the test once we know the 3nd frame drew. - if (layer_tree_host()->source_frame_number() < 4) { + if (layer_tree_host()->source_frame_number() < 5) { layer_tree_host()->root_layer()->SetNeedsDisplay(); layer_tree_host()->SetNeedsCommit(); } else { diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index c89b15d..6df0b585 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -17,6 +17,8 @@ LayerTreeSettings::LayerTreeSettings() allow_antialiasing(true), throttle_frame_production(true), begin_impl_frame_scheduling_enabled(false), + main_frame_before_draw_enabled(true), + main_frame_before_activation_enabled(false), using_synchronous_renderer_compositor(false), per_tile_painting_enabled(false), partial_swap_enabled(false), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 52f0d41..3ad7bf3 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -22,6 +22,8 @@ class CC_EXPORT LayerTreeSettings { bool allow_antialiasing; bool throttle_frame_production; bool begin_impl_frame_scheduling_enabled; + bool main_frame_before_draw_enabled; + bool main_frame_before_activation_enabled; bool using_synchronous_renderer_compositor; bool per_tile_painting_enabled; bool partial_swap_enabled; diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 58e89b0..bf55546f 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -984,8 +984,6 @@ void ThreadProxy::StartCommitOnImplThread( CompletionEvent* completion, ResourceUpdateQueue* raw_queue, scoped_refptr<ContextProvider> offscreen_context_provider) { - scoped_ptr<ResourceUpdateQueue> queue(raw_queue); - TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread"); DCHECK(!impl().commit_completion_event); DCHECK(IsImplThread() && IsMainThreadBlocked()); @@ -1003,6 +1001,8 @@ void ThreadProxy::StartCommitOnImplThread( // But, we can avoid a PostTask in here. impl().scheduler->NotifyBeginMainFrameStarted(); + scoped_ptr<ResourceUpdateQueue> queue(raw_queue); + if (offscreen_context_provider.get()) offscreen_context_provider->BindToCurrentThread(); impl().layer_tree_host_impl->SetOffscreenContextProvider( @@ -1465,6 +1465,10 @@ void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { layer_tree_host()->CreateLayerTreeHostImpl(this); const LayerTreeSettings& settings = layer_tree_host()->settings(); SchedulerSettings scheduler_settings; + scheduler_settings.main_frame_before_draw_enabled = + settings.main_frame_before_draw_enabled; + scheduler_settings.main_frame_before_activation_enabled = + settings.main_frame_before_activation_enabled; scheduler_settings.impl_side_painting = settings.impl_side_painting; scheduler_settings.timeout_and_draw_when_animation_checkerboards = settings.timeout_and_draw_when_animation_checkerboards; |