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

Unified Diff: cc/scheduler/scheduler_unittest.cc

Issue 1133673004: cc: Heuristic for Renderer latency recovery (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: improve test readability and coverage Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/scheduler/scheduler_unittest.cc
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index 29505e5a9b76197de307feae951fb44f0565c5c0..a42b7f4d1c6717cc1b0c467a50efaf92bf4c7ef4 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -246,6 +246,16 @@ class SchedulerTest : public testing::Test {
fake_compositor_timing_history.Pass());
DCHECK(scheduler_);
client_->set_scheduler(scheduler_.get());
+
+ // Use large estimates by default to avoid latency recovery
+ // in most tests.
+ base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ one_second);
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ one_second);
+ fake_compositor_timing_history_->SetDrawDurationEstimate(one_second);
+
return scheduler_.get();
}
@@ -384,11 +394,9 @@ class SchedulerTest : public testing::Test {
return fake_external_begin_frame_source_.get();
}
- void MainFrameInHighLatencyMode(
- int64 begin_main_frame_to_commit_estimate_in_ms,
- int64 commit_to_activate_estimate_in_ms,
- bool impl_latency_takes_priority,
- bool should_send_begin_main_frame);
+ void MainFrameInHighLatencyMode(bool should_send_begin_main_frame);
+ void ImplFrameInHighLatencySkipImplFrame(bool swap_ack_before_deadline);
+ void ImplFrameInHighLatencyDontSkipImplFrame();
void BeginFramesNotFromClient(bool use_external_begin_frame_source,
bool throttle_frame_production);
void BeginFramesNotFromClient_SwapThrottled(
@@ -1290,23 +1298,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
}
void SchedulerTest::MainFrameInHighLatencyMode(
mithro-old 2015/07/08 00:54:51 nit: I think this could be named better. My thoug
- int64 begin_main_frame_to_commit_estimate_in_ms,
- int64 commit_to_activate_estimate_in_ms,
- bool impl_latency_takes_priority,
- bool should_send_begin_main_frame) {
- scheduler_settings_.use_external_begin_frame_source = true;
- SetUpScheduler(true);
-
- fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
- base::TimeDelta::FromMilliseconds(
- begin_main_frame_to_commit_estimate_in_ms));
- fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
- base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
- fake_compositor_timing_history_->SetDrawDurationEstimate(
- base::TimeDelta::FromMilliseconds(1));
-
- scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority);
-
+ bool expect_send_begin_main_frame) {
// Impl thread hits deadline before commit finishes.
scheduler_->SetNeedsCommit();
EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
@@ -1326,36 +1318,394 @@ void SchedulerTest::MainFrameInHighLatencyMode(
EXPECT_SCOPED(AdvanceFrame());
EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(),
- should_send_begin_main_frame);
- EXPECT_EQ(client_->HasAction("ScheduledActionSendBeginMainFrame"),
- should_send_begin_main_frame);
+ EXPECT_EQ(expect_send_begin_main_frame,
+ scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_EQ(expect_send_begin_main_frame,
+ client_->HasAction("ScheduledActionSendBeginMainFrame"));
+}
+
+TEST_F(SchedulerTest, SkipMainFrameIfHighLatencyAndCanDrawBeforeDeadline) {
mithro-old 2015/07/08 00:54:51 nit: s/IfHighLatency/IfLateCommit/ or maybe IfMiss
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool expect_send_begin_main_frame = false;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+TEST_F(SchedulerTest, DontSkipMainFrameInPreferImplLatencyMode) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ scheduler_->SetImplLatencyTakesPriority(true);
+
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+TEST_F(SchedulerTest, DontSkipMainFrameIfCommitEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
mithro-old 2015/07/08 00:54:51 nit: It seems like it could be dangerous to be usi
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
mithro-old 2015/07/08 00:54:51 nit: Should we use a larger value here?
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+TEST_F(SchedulerTest, DontSkipMainFrameIfReadyToActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+TEST_F(SchedulerTest, DontSkipMainFrameIfActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetActivateDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+TEST_F(SchedulerTest, DontSkipMainFrameIfDrawEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetDrawDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ bool expect_send_begin_main_frame = true;
+ EXPECT_SCOPED(MainFrameInHighLatencyMode(expect_send_begin_main_frame));
+}
+
+void SchedulerTest::ImplFrameInHighLatencySkipImplFrame(
mithro-old 2015/07/08 00:54:51 nit: Name - see comments above too.
+ bool swap_ack_before_deadline) {
+ // Set up client with specified estimates.
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ // Use estimates that indicate commit and activate can finish before the
+ // deadline.
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Draw and swap for first BeginFrame
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 4);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 4);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Verify we skip every other frame if the swap ack consistently
+ // comes back late.
+ for (int i = 0; i < 10; i++) {
+ // Not calling scheduler_->DidSwapBuffersComplete() until after next
+ // BeginImplFrame puts the impl thread in high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ // Verify that we skip the BeginImplFrame
+ EXPECT_NO_ACTION(client_);
+ EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ // Verify that we do not perform any actions after we are no longer
+ // swap throttled.
+ // Also verify the scheduler logic that determines if we are in a high
mithro-old 2015/07/08 00:54:51 Where is the verification that this comment is ref
+ // latency mode is immune to whether or not the swap ack comes back before
+ // or after the deadline.
+ client_->Reset();
+ if (swap_ack_before_deadline) {
+ scheduler_->DidSwapBuffersComplete();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ } else {
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ scheduler_->DidSwapBuffersComplete();
+ }
+ EXPECT_NO_ACTION(client_);
+
+ // Verify that we start the next BeginImplFrame and continue normally
+ // after having just skipped a BeginImplFrame.
+ client_->Reset();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->SetNeedsCommit();
+ scheduler_->SetNeedsRedraw();
+ SendNextBeginFrame();
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+ }
}
TEST_F(SchedulerTest,
- SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
- // Set up client so that estimates indicate that we can commit and activate
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false));
+ SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_SwapAckThenDeadline) {
+ bool swap_ack_before_deadline = true;
+ EXPECT_SCOPED(ImplFrameInHighLatencySkipImplFrame(swap_ack_before_deadline));
}
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
- // Set up client so that estimates indicate that the commit cannot finish
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true));
+TEST_F(SchedulerTest,
+ SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_DeadlineThenSwapAck) {
+ bool swap_ack_before_deadline = false;
+ EXPECT_SCOPED(ImplFrameInHighLatencySkipImplFrame(swap_ack_before_deadline));
}
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
- // Set up client so that estimates indicate that the activate cannot finish
- // before the deadline (~8ms by default).
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true));
+void SchedulerTest::ImplFrameInHighLatencyDontSkipImplFrame() {
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Draw and swap for first BeginFrame
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
+
+ client_->Reset();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
+
+ // Verify impl thread consistently operates in high latency mode
+ // without skipping any frames.
+ for (int i = 0; i < 10; i++) {
+ // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
+ // puts the impl thread in high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
+ EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ client_->Reset();
+ scheduler_->DidSwapBuffersComplete();
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+
+ // Verify that we don't skip the actions of the BeginImplFrame
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
+ }
}
-TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
- // Set up client so that estimates indicate that we can commit and activate
- // before the deadline (~8ms by default), but also enable impl latency takes
- // priority mode.
- EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true));
+TEST_F(SchedulerTest, DontSkipImplFrameIfCommitEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ EXPECT_SCOPED(ImplFrameInHighLatencyDontSkipImplFrame());
+}
+
+TEST_F(SchedulerTest, DontSkipImplFrameIfReadyToActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ EXPECT_SCOPED(ImplFrameInHighLatencyDontSkipImplFrame());
+}
+
+TEST_F(SchedulerTest, DontSkipImplFrameIfActivateEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetActivateDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ EXPECT_SCOPED(ImplFrameInHighLatencyDontSkipImplFrame());
+}
+
+TEST_F(SchedulerTest, DontSkipImplFrameIfDrawEstimateTooLong) {
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetDrawDurationEstimate(
+ base::TimeDelta::FromMilliseconds(16));
+ EXPECT_SCOPED(ImplFrameInHighLatencyDontSkipImplFrame());
+}
+
+TEST_F(SchedulerTest, MainAndSwapInHighLatencyMode) {
+ // Set up client with custom estimates.
+ // This test starts off with expensive estimates to prevent latency recovery
+ // initially, then lowers the estimates to enable it once both the main
+ // and impl threads are in a high latency mode.
+ scheduler_settings_.use_external_begin_frame_source = true;
+ SetUpScheduler(true);
+
+ auto slow_duration = base::TimeDelta::FromMilliseconds(16);
+ fake_compositor_timing_history_->SetAllEstimatesTo(base::TimeDelta());
+ fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
+
+ // To get into a high latency state, this test disables automatic swap acks.
+ scheduler_->SetMaxSwapsPending(1);
+ client_->SetAutomaticSwapAck(false);
+
+ // Impl thread hits deadline before commit finishes to make
+ // MainThreadIsInHighLatencyMode true
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
+ EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
+
+ // Draw and swap for first commit, start second commit.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6);
+
+ // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
+ // to put the impl thread in a high latency mode.
+ client_->Reset();
+ scheduler_->SetNeedsCommit();
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ EXPECT_SCOPED(AdvanceFrame());
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ scheduler_->DidSwapBuffersComplete();
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
+ // Note: BeginMainFrame and swap are skipped here because of
+ // swap ack backpressure, not because of latency recovery.
+ EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
+ EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
+
+ // Lower estimates so that the scheduler will attempt latency recovery.
+ auto fast_duration = base::TimeDelta::FromMilliseconds(1);
+ fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
+
+ // Now that both threads are in a high latency mode, make sure we
+ // skip the BeginMainFrame, then the BeginImplFrame, but not both
+ // at the same time.
+
+ // Verify we skip BeginMainFrame first.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3);
+ EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
+
+ // Verify we skip the BeginImplFrame second.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_NO_ACTION(client_);
+
+ // Then verify we operate in a low latency mode.
+ client_->Reset();
+ // Previous commit request is still outstanding.
+ EXPECT_TRUE(scheduler_->NeedsCommit());
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ SendNextBeginFrame();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->NotifyBeginMainFrameStarted();
+ scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToActivate();
+ task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+ scheduler_->DidSwapBuffersComplete();
+ EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
+
+ EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
+ EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6);
+ EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6);
+ EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6);
+ EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6);
}
TEST_F(
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698