Index: cc/scheduler/scheduler_unittest.cc |
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc |
index ff8b11dc68c52ddd96a6afed523e18937698f7a3..a1da822cff182dc05500b24b5d66139f2f1aeaae 100644 |
--- a/cc/scheduler/scheduler_unittest.cc |
+++ b/cc/scheduler/scheduler_unittest.cc |
@@ -1,7 +1,6 @@ |
// Copyright 2011 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
- |
#include "cc/scheduler/scheduler.h" |
#include <string> |
@@ -35,9 +34,10 @@ void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler) { |
scheduler->FinishCommit(); |
// Go through the motions to draw the commit. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- // We need another BeginFrame so scheduler calls SetNeedsBeginFrame(false). |
- scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
+ // We need another BeginFrame so Scheduler calls SetNeedsBeginFrame(false). |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
} |
class FakeSchedulerClient : public SchedulerClient { |
@@ -156,6 +156,14 @@ class FakeSchedulerClient : public SchedulerClient { |
return base::TimeDelta(); |
} |
+ virtual void PostBeginFrameDeadline(const base::Closure& closure, |
+ base::TimeTicks deadline) OVERRIDE { |
+ actions_.push_back("PostBeginFrameDeadlineTask"); |
+ states_.push_back(scheduler_->StateAsValue().release()); |
+ } |
+ |
+ virtual void DidBeginFrameDeadlineOnImplThread() OVERRIDE {} |
+ |
protected: |
bool needs_begin_frame_; |
bool draw_will_happen_; |
@@ -180,10 +188,11 @@ TEST(SchedulerTest, InitializeOutputSurfaceDoesNotBeginFrame) { |
EXPECT_EQ(0, client.num_actions_()); |
} |
-TEST(SchedulerTest, RequestCommit) { |
+void RequestCommit(bool deadline_scheduling_enabled) { |
FakeSchedulerClient client; |
- SchedulerSettings default_scheduler_settings; |
- Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ SchedulerSettings scheduler_settings; |
+ scheduler_settings.deadline_scheduling_enabled = deadline_scheduling_enabled; |
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
@@ -191,11 +200,32 @@ TEST(SchedulerTest, RequestCommit) { |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
InitializeOutputSurfaceAndFirstCommit(scheduler); |
- // SetNeedsCommit should begin the frame. |
+ // SetNeedsCommit should begin the frame on the next BeginFrame. |
client.Reset(); |
scheduler->SetNeedsCommit(); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ } else { |
+ EXPECT_EQ(client.num_actions_(), 2); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginFrameToMainThread")); |
+ EXPECT_TRUE(client.HasAction("SetNeedsBeginFrameOnImplThread")); |
+ } |
+ client.Reset(); |
+ |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
+ |
+ // If we don't swap on the deadline, we need to request another BeginFrame. |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
@@ -205,18 +235,47 @@ TEST(SchedulerTest, RequestCommit) { |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
- // BeginFrame should draw. |
+ // BeginFrame should prepare the draw. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
+ |
+ // BeginFrame deadline should draw. |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
+ |
+ // The following BeginFrame deadline should SetNeedsBeginFrame(false) to avoid |
+ // excessive toggles. |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ EXPECT_FALSE(client.needs_begin_frame()); |
+ client.Reset(); |
} |
-TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { |
+TEST(SchedulerTest, RequestCommit) { |
+ bool deadline_scheduling_enabled = false; |
+ RequestCommit(deadline_scheduling_enabled); |
+} |
+ |
+TEST(SchedulerTest, RequestCommit_Deadline) { |
+ bool deadline_scheduling_enabled = true; |
+ RequestCommit(deadline_scheduling_enabled); |
+} |
+ |
+void RequestCommitAfterBeginFrameSentToMainThread( |
+ bool deadline_scheduling_enabled) { |
FakeSchedulerClient client; |
- SchedulerSettings default_scheduler_settings; |
- Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ SchedulerSettings scheduler_settings; |
+ scheduler_settings.deadline_scheduling_enabled = deadline_scheduling_enabled; |
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
@@ -225,49 +284,102 @@ TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { |
InitializeOutputSurfaceAndFirstCommit(scheduler); |
client.Reset(); |
- // SetNedsCommit should begin the frame. |
+ // SetNeedsCommit should begin the frame. |
scheduler->SetNeedsCommit(); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ } else { |
+ EXPECT_EQ(client.num_actions_(), 2); |
+ EXPECT_TRUE(client.HasAction("SetNeedsBeginFrameOnImplThread")); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginFrameToMainThread")); |
+ } |
+ |
client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_EQ(client.num_actions_(), 2); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginFrameToMainThread")); |
+ EXPECT_TRUE(client.HasAction("PostBeginFrameDeadlineTask")); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
- // Now SetNeedsCommit again. Calling here means we need a second frame. |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
+ |
+ // Now SetNeedsCommit again. Calling here means we need a second commit. |
scheduler->SetNeedsCommit(); |
+ EXPECT_EQ(client.num_actions_(), 0); |
+ client.Reset(); |
- // Finish the commit for the first frame. |
+ // Finish the first commit. |
scheduler->FinishCommit(); |
- EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); |
+ EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ } else { |
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 3); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); |
+ } |
- // Tick should draw but then begin another frame for the second commit. |
// Because we just swapped, the Scheduler should also request the next |
// BeginFrame from the OutputSurface. |
- scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
EXPECT_TRUE(client.needs_begin_frame()); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 3); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); |
client.Reset(); |
- // Finish the second commit. |
- scheduler->FinishCommit(); |
+ // Since another commit is needed, the next BeginFrame should initiate |
+ // the second commit. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_ACTION("ScheduledActionCommit", client, 0, 3); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 3); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_EQ(client.num_actions_(), 2); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginFrameToMainThread")); |
+ EXPECT_TRUE(client.HasAction("PostBeginFrameDeadlineTask")); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
+ client.Reset(); |
+ |
+ // Finishing the commit before the deadline should post a new deadline task |
+ // to trigger the deadline early. |
+ scheduler->FinishCommit(); |
+ EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
// On the next BeginFrame, verify we go back to a quiescent state and |
// no longer request BeginFrames. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_FALSE(client.needs_begin_frame()); |
+ client.Reset(); |
} |
-TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
+TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { |
+ bool deadline_scheduling_enabled = false; |
+ RequestCommitAfterBeginFrameSentToMainThread(deadline_scheduling_enabled); |
+} |
+ |
+TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread_Deadline) { |
+ bool deadline_scheduling_enabled = true; |
+ RequestCommitAfterBeginFrameSentToMainThread(deadline_scheduling_enabled); |
+} |
+ |
+void TextureAcquisitionCausesCommitInsteadOfDraw( |
+ bool deadline_scheduling_enabled) { |
FakeSchedulerClient client; |
- SchedulerSettings default_scheduler_settings; |
- Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ SchedulerSettings scheduler_settings; |
+ scheduler_settings.deadline_scheduling_enabled = deadline_scheduling_enabled; |
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
@@ -282,6 +394,9 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
EXPECT_FALSE(scheduler->RedrawPending()); |
@@ -289,6 +404,9 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
EXPECT_FALSE(scheduler->RedrawPending()); |
EXPECT_FALSE(client.needs_begin_frame()); |
@@ -308,25 +426,40 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
// No draw happens since the textures are acquired by the main thread. |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
EXPECT_TRUE(scheduler->RedrawPending()); |
EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
scheduler->SetNeedsCommit(); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); |
- EXPECT_TRUE(client.needs_begin_frame()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_EQ(0, client.num_actions_()); |
+ } else { |
+ EXPECT_SINGLE_ACTION("ScheduledActionSendBeginFrameToMainThread", client); |
+ } |
+ |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
// Commit will release the texture. |
client.Reset(); |
scheduler->FinishCommit(); |
- EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); |
+ EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
EXPECT_TRUE(scheduler->RedrawPending()); |
- EXPECT_TRUE(client.needs_begin_frame()); |
// Now we can draw again after the commit happens. |
client.Reset(); |
- scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
EXPECT_FALSE(scheduler->RedrawPending()); |
@@ -335,14 +468,28 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
// Make sure we stop requesting BeginFrames if we don't swap. |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
EXPECT_FALSE(client.needs_begin_frame()); |
} |
-TEST(SchedulerTest, TextureAcquisitionCollision) { |
+TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
+ bool deadline_scheduling_enabled = false; |
+ TextureAcquisitionCausesCommitInsteadOfDraw(deadline_scheduling_enabled); |
+} |
+ |
+TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw_Deadline) { |
+ bool deadline_scheduling_enabled = true; |
+ TextureAcquisitionCausesCommitInsteadOfDraw(deadline_scheduling_enabled); |
+} |
+ |
+void TextureAcquisitionCollision(bool deadline_scheduling_enabled) { |
FakeSchedulerClient client; |
- SchedulerSettings default_scheduler_settings; |
- Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ SchedulerSettings scheduler_settings; |
+ scheduler_settings.deadline_scheduling_enabled = deadline_scheduling_enabled; |
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
@@ -352,12 +499,30 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { |
client.Reset(); |
scheduler->SetNeedsCommit(); |
+if (deadline_scheduling_enabled) { |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ } else { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ } |
+ |
+ client.Reset(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 3); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 3); |
- EXPECT_ACTION( |
- "ScheduledActionAcquireLayerTexturesForMainThread", client, 2, 3); |
+ EXPECT_SINGLE_ACTION( |
+ "ScheduledActionAcquireLayerTexturesForMainThread", client); |
+ |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
+ |
client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
// Although the compositor cannot draw because textures are locked by main |
// thread, we continue requesting SetNeedsBeginFrame in anticipation of the |
@@ -367,56 +532,88 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { |
// Trigger the commit |
scheduler->FinishCommit(); |
EXPECT_TRUE(client.needs_begin_frame()); |
- client.Reset(); |
// Between commit and draw, texture acquisition for main thread delayed, |
// and main thread blocks. |
+ client.Reset(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
EXPECT_EQ(0, client.num_actions_()); |
- client.Reset(); |
// No implicit commit is expected. |
+ client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); |
- EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
- client, |
- 1, |
- 3); |
+ EXPECT_ACTION( |
+ "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 3); |
EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); |
EXPECT_TRUE(client.needs_begin_frame()); |
- client.Reset(); |
- // Compositor not scheduled to draw because textures are locked by main |
+ // The compositor should not draw because textures are locked by main |
// thread. |
+ client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
EXPECT_FALSE(client.needs_begin_frame()); |
- client.Reset(); |
- // Needs an explicit commit from the main thread. |
+ // The impl thread need an explicit commit from the main thread to lock |
+ // the textures. |
+ client.Reset(); |
scheduler->SetNeedsCommit(); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ } else { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ } |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ if (deadline_scheduling_enabled) { |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ } else { |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ } |
client.Reset(); |
- // Trigger the commit |
+ // Trigger the commit, which will trigger the deadline task early. |
scheduler->FinishCommit(); |
- EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); |
+ EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
- // Verify we draw on the next BeginFrame. |
- scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ // Verify we draw on the next BeginFrame deadline |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
} |
-TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
+TEST(SchedulerTest, TextureAcquisitionCollision) { |
+ bool deadline_scheduling_enabled = false; |
+ TextureAcquisitionCollision(deadline_scheduling_enabled); |
+} |
+ |
+TEST(SchedulerTest, TextureAcquisitionCollision_Deadline) { |
+ bool deadline_scheduling_enabled = true; |
+ TextureAcquisitionCollision(deadline_scheduling_enabled); |
+} |
+ |
+void VisibilitySwitchWithTextureAcquisition(bool deadline_scheduling_enabled) { |
FakeSchedulerClient client; |
- SchedulerSettings default_scheduler_settings; |
- Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ SchedulerSettings scheduler_settings; |
+ scheduler_settings.deadline_scheduling_enabled = deadline_scheduling_enabled; |
+ Scheduler* scheduler = client.CreateScheduler(scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
@@ -426,6 +623,10 @@ TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
scheduler->DidCreateAndInitializeOutputSurface(); |
scheduler->SetNeedsCommit(); |
+ if (deadline_scheduling_enabled) { |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
+ } |
scheduler->FinishCommit(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
scheduler->SetNeedsCommit(); |
@@ -435,19 +636,29 @@ TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
scheduler->SetVisible(false); |
EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
client); |
- client.Reset(); |
- // Already sent a begin frame on this current frame, so wait. |
+ client.Reset(); |
scheduler->SetVisible(true); |
EXPECT_EQ(0, client.num_actions_()); |
- client.Reset(); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
// Regaining visibility with textures acquired by main thread while |
// compositor is waiting for first draw should result in a request |
// for a new frame in order to escape a deadlock. |
+ client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+} |
+ |
+TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
+ bool deadline_scheduling_enabled = false; |
+ VisibilitySwitchWithTextureAcquisition(deadline_scheduling_enabled); |
+} |
+ |
+TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition_Deadline) { |
+ bool deadline_scheduling_enabled = true; |
+ VisibilitySwitchWithTextureAcquisition(deadline_scheduling_enabled); |
} |
class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { |
@@ -494,17 +705,20 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { |
EXPECT_EQ(0, client.num_draws()); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
EXPECT_TRUE(scheduler->RedrawPending()); |
EXPECT_TRUE(client.needs_begin_frame()); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
EXPECT_FALSE(scheduler->RedrawPending()); |
EXPECT_TRUE(client.needs_begin_frame()); |
// We stop requesting BeginFrames after a BeginFrame where we don't swap. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
EXPECT_FALSE(scheduler->RedrawPending()); |
EXPECT_FALSE(client.needs_begin_frame()); |
@@ -530,6 +744,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
// Fail the draw. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
// We have a commit pending and the draw failed, and we didn't lose the redraw |
@@ -540,6 +755,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
// Fail the draw again. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
EXPECT_TRUE(scheduler->CommitPending()); |
EXPECT_TRUE(scheduler->RedrawPending()); |
@@ -548,6 +764,7 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
// Draw successfully. |
client.SetDrawWillHappen(true); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(3, client.num_draws()); |
EXPECT_TRUE(scheduler->CommitPending()); |
EXPECT_FALSE(scheduler->RedrawPending()); |
@@ -600,6 +817,7 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { |
InitializeOutputSurfaceAndFirstCommit(scheduler); |
client.Reset(); |
+ EXPECT_FALSE(client.needs_begin_frame()); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
EXPECT_EQ(0, client.num_draws()); |
@@ -607,19 +825,24 @@ TEST(SchedulerTest, RequestCommitInsideDraw) { |
client.SetNeedsCommitOnNextDraw(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ client.SetNeedsCommitOnNextDraw(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
EXPECT_TRUE(scheduler->CommitPending()); |
EXPECT_TRUE(client.needs_begin_frame()); |
scheduler->FinishCommit(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_EQ(2, client.num_draws());; |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_EQ(2, client.num_draws()); |
+ |
EXPECT_FALSE(scheduler->RedrawPending()); |
EXPECT_FALSE(scheduler->CommitPending()); |
EXPECT_TRUE(client.needs_begin_frame()); |
// We stop requesting BeginFrames after a BeginFrame where we don't swap. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
EXPECT_FALSE(scheduler->RedrawPending()); |
EXPECT_FALSE(scheduler->CommitPending()); |
@@ -646,6 +869,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
// Fail the draw. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
// We have a commit pending and the draw failed, and we didn't lose the commit |
@@ -656,6 +880,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
// Fail the draw again. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
EXPECT_TRUE(scheduler->CommitPending()); |
EXPECT_TRUE(scheduler->RedrawPending()); |
@@ -664,6 +889,7 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
// Draw successfully. |
client.SetDrawWillHappen(true); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(3, client.num_draws()); |
EXPECT_TRUE(scheduler->CommitPending()); |
EXPECT_FALSE(scheduler->RedrawPending()); |
@@ -688,6 +914,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { |
// Draw successfully, this starts a new frame. |
client.SetNeedsCommitOnNextDraw(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
scheduler->SetNeedsRedraw(); |
@@ -698,6 +925,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { |
client.SetDrawWillHappen(false); |
client.SetNeedsCommitOnNextDraw(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
} |
@@ -774,8 +1002,16 @@ TEST(SchedulerTest, ManageTiles) { |
EXPECT_EQ(0, client.num_draws()); |
EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles")); |
EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); |
+ |
+ // We have no immediate actions to perform, so the BeginFrame should post |
+ // the deadline task. |
+ client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- // The actions should have occured, in the right order. |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ |
+ // On the deadline, he actions should have occured in the right order. |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); |
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); |
@@ -792,10 +1028,17 @@ TEST(SchedulerTest, ManageTiles) { |
EXPECT_TRUE(client.needs_begin_frame()); |
EXPECT_EQ(0, client.num_draws()); |
+ // We have no immediate actions to perform, so the BeginFrame should post |
+ // the deadline task. |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ |
// Draw. The draw will trigger SetNeedsManageTiles, and |
// then the ManageTiles action will be triggered after the Draw. |
// Afterwards, neither a draw nor ManageTiles are pending. |
- scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); |
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); |
@@ -807,7 +1050,10 @@ TEST(SchedulerTest, ManageTiles) { |
// We need a BeginFrame where we don't swap to go idle. |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);; |
EXPECT_EQ(0, client.num_draws()); |
// Now trigger a ManageTiles outside of a draw. We will then need |
@@ -820,7 +1066,11 @@ TEST(SchedulerTest, ManageTiles) { |
EXPECT_FALSE(scheduler->RedrawPending()); |
// BeginFrame. There will be no draw, only ManageTiles. |
+ client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(0, client.num_draws()); |
EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible")); |
EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles")); |