Index: cc/scheduler/scheduler_unittest.cc |
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc |
index 930111c1b2a7fd1c104bd48108b6a7e7f6b06a4f..3fc0400a795fb60403ddcfaaedea17b81274d240 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> |
@@ -28,6 +27,19 @@ |
namespace cc { |
namespace { |
+void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler) { |
+ scheduler->DidCreateAndInitializeOutputSurface(); |
+ scheduler->SetNeedsCommit(); |
+ scheduler->FinishCommit(); |
+ scheduler->SetHasTrees(0, 0); |
+ // Go through the motions to draw the commit. |
+ 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 { |
public: |
FakeSchedulerClient() |
@@ -78,21 +90,26 @@ class FakeSchedulerClient : public SchedulerClient { |
actions_.push_back("ScheduledActionSendBeginFrameToMainThread"); |
states_.push_back(scheduler_->StateAsStringForTesting()); |
} |
- virtual ScheduledActionDrawAndSwapResult |
- ScheduledActionDrawAndSwapIfPossible() OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
+ OVERRIDE { |
actions_.push_back("ScheduledActionDrawAndSwapIfPossible"); |
states_.push_back(scheduler_->StateAsStringForTesting()); |
num_draws_++; |
- return ScheduledActionDrawAndSwapResult(draw_will_happen_, |
- draw_will_happen_ && |
- swap_will_happen_if_draw_happens_); |
+ return DrawSwapReadbackResult( |
+ draw_will_happen_, |
+ draw_will_happen_ && swap_will_happen_if_draw_happens_, |
+ false); |
} |
- virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() |
- OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
actions_.push_back("ScheduledActionDrawAndSwapForced"); |
states_.push_back(scheduler_->StateAsStringForTesting()); |
- return ScheduledActionDrawAndSwapResult(true, |
- swap_will_happen_if_draw_happens_); |
+ return DrawSwapReadbackResult( |
+ true, swap_will_happen_if_draw_happens_, false); |
+ } |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() OVERRIDE { |
+ actions_.push_back("ScheduledActionDrawAndReadback"); |
+ states_.push_back(scheduler_->StateAsStringForTesting()); |
+ return DrawSwapReadbackResult(true, false, true); |
} |
virtual void ScheduledActionCommit() OVERRIDE { |
actions_.push_back("ScheduledActionCommit"); |
@@ -102,8 +119,8 @@ class FakeSchedulerClient : public SchedulerClient { |
actions_.push_back("ScheduledActionUpdateVisibleTiles"); |
states_.push_back(scheduler_->StateAsStringForTesting()); |
} |
- virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE { |
- actions_.push_back("ScheduledActionActivatePendingTreeIfNeeded"); |
+ virtual void ScheduledActionActivatePendingTree() OVERRIDE { |
+ actions_.push_back("ScheduledActionActivatePendingTree"); |
states_.push_back(scheduler_->StateAsStringForTesting()); |
} |
virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { |
@@ -125,6 +142,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_->StateAsStringForTesting()); |
+ } |
+ |
+ virtual void DidBeginFrameDeadlineOnImplThread() OVERRIDE {} |
+ |
protected: |
bool needs_begin_frame_; |
bool draw_will_happen_; |
@@ -158,27 +183,51 @@ TEST(SchedulerTest, RequestCommit) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- client.Reset(); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
- // SetNeedsCommit should begin the frame. |
+ // SetNeedsCommit should begin the frame on the next BeginFrame. |
+ client.Reset(); |
scheduler->SetNeedsCommit(); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
+ |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ 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(); |
// FinishCommit should commit |
scheduler->FinishCommit(); |
- EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); |
EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
- // BeginFrame should draw. |
+ // BeginFrame should prepare the draw. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ client.Reset(); |
+ |
+ // BeginFrame deadline should draw. |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
+ 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(); |
} |
@@ -192,38 +241,56 @@ TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
client.Reset(); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
- // SetNedsCommit should begin the frame. |
+ // SetNeddsCommit should begin the frame. |
scheduler->SetNeedsCommit(); |
+ EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
client.Reset(); |
- // Now SetNeedsCommit again. Calling here means we need a second frame. |
+ // Now SetNeedsCommit again. Calling here means we need a second commit. |
scheduler->SetNeedsCommit(); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 1); |
+ EXPECT_EQ(client.num_actions_(), 0); |
client.Reset(); |
- // Since another commit is needed, FinishCommit should commit, |
- // then begin another frame. |
+ // Finish the first commit. |
scheduler->FinishCommit(); |
EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
client.Reset(); |
- // Tick should draw but then begin another frame. |
+ // Since another commit is needed, the next BeginFrame should initiate |
+ // the second commit. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_TRUE(client.needs_begin_frame()); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
client.Reset(); |
- // Go back to quiescent state and verify we no longer request BeginFrames. |
+ // 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_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ |
+ // On the next BeginFrame, go back to quiescent state and verify we no longer |
+ // request BeginFrames. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_FALSE(client.needs_begin_frame()); |
+ client.Reset(); |
} |
TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
@@ -235,8 +302,8 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
client.Reset(); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
@@ -244,10 +311,12 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
client.Reset(); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ |
+ client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
EXPECT_FALSE(scheduler->RedrawPending()); |
- EXPECT_FALSE(client.needs_begin_frame()); |
client.Reset(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
@@ -258,36 +327,47 @@ TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
client.Reset(); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
- EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
- EXPECT_TRUE(client.needs_begin_frame()); |
+ EXPECT_EQ(0, client.num_actions_()); |
// 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()); |
+ EXPECT_EQ(0, client.num_actions_()); |
+ |
+ client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
// 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()); |
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
EXPECT_FALSE(scheduler->RedrawPending()); |
+ |
+ // SetNeedsBeginFrame(false) should be deferred to the end of the next |
+ // BeginFrame to avoid excessive toggling. |
+ EXPECT_TRUE(client.needs_begin_frame()); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_FALSE(client.needs_begin_frame()); |
- client.Reset(); |
} |
TEST(SchedulerTest, TextureAcquisitionCollision) { |
@@ -299,19 +379,23 @@ TEST(SchedulerTest, TextureAcquisitionCollision) { |
scheduler->SetCanDraw(true); |
EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
- client.Reset(); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
scheduler->SetNeedsCommit(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
- EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 4); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 4); |
- EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
- client, |
- 2, |
- 4); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 3, 4); |
+ EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2); |
+ EXPECT_ACTION( |
+ "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2); |
+ |
client.Reset(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
+ |
+ 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 |
@@ -321,32 +405,34 @@ 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_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); |
- EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
- client, |
- 1, |
- 3); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); |
+ EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
+ |
client.Reset(); |
+ scheduler->OnBeginFrameDeadline(); |
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
+ EXPECT_ACTION( |
+ "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2); |
- // Compositor not scheduled to draw because textures are locked by main |
- // thread. |
- EXPECT_FALSE(client.needs_begin_frame()); |
+ // Although the compositor is not scheduled to draw because textures are |
+ // locked by main thread, we proactively request the begin frame. |
+ EXPECT_TRUE(client.needs_begin_frame()); |
// Needs an explicit commit from the main thread. |
+ client.Reset(); |
scheduler->SetNeedsCommit(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
- EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); |
+ EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
client.Reset(); |
// Trigger the commit |
@@ -367,6 +453,8 @@ TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
scheduler->DidCreateAndInitializeOutputSurface(); |
scheduler->SetNeedsCommit(); |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
scheduler->FinishCommit(); |
scheduler->SetMainThreadNeedsLayerTextures(); |
scheduler->SetNeedsCommit(); |
@@ -376,36 +464,36 @@ 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); |
} |
class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { |
public: |
virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} |
- virtual ScheduledActionDrawAndSwapResult |
- ScheduledActionDrawAndSwapIfPossible() OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
+ OVERRIDE { |
// Only SetNeedsRedraw the first time this is called |
if (!num_draws_) |
scheduler_->SetNeedsRedraw(); |
return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
} |
- virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() |
- OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
NOTREACHED(); |
- return ScheduledActionDrawAndSwapResult(true, true); |
+ return DrawSwapReadbackResult(true, true, false); |
} |
virtual void ScheduledActionCommit() OVERRIDE {} |
@@ -424,7 +512,8 @@ TEST(SchedulerTest, RequestRedrawInsideDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
@@ -432,13 +521,19 @@ 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()); |
+ |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_FALSE(client.needs_begin_frame()); |
} |
@@ -450,7 +545,8 @@ TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
client.SetDrawWillHappen(false); |
@@ -461,6 +557,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 |
@@ -471,6 +568,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()); |
@@ -479,60 +577,80 @@ 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()); |
EXPECT_TRUE(client.needs_begin_frame()); |
} |
-class SchedulerClientThatsetNeedsCommitInsideDraw : public FakeSchedulerClient { |
+class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient { |
public: |
+ SchedulerClientThatSetNeedsCommitInsideDraw() |
+ : set_needs_commit_on_next_draw_(false) {} |
+ |
virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} |
- virtual ScheduledActionDrawAndSwapResult |
- ScheduledActionDrawAndSwapIfPossible() OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
+ OVERRIDE { |
// Only SetNeedsCommit the first time this is called |
- if (!num_draws_) |
+ if (set_needs_commit_on_next_draw_) { |
scheduler_->SetNeedsCommit(); |
+ set_needs_commit_on_next_draw_ = false; |
+ } |
return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
} |
- virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() |
- OVERRIDE { |
+ virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
NOTREACHED(); |
- return ScheduledActionDrawAndSwapResult(true, true); |
+ return DrawSwapReadbackResult(true, true, false); |
} |
virtual void ScheduledActionCommit() OVERRIDE {} |
virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} |
virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} |
+ |
+ void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; } |
+ |
+ private: |
+ bool set_needs_commit_on_next_draw_; |
}; |
// Tests for the scheduler infinite-looping on SetNeedsCommit requests that |
// happen inside a ScheduledActionDrawAndSwap |
TEST(SchedulerTest, RequestCommitInsideDraw) { |
- SchedulerClientThatsetNeedsCommitInsideDraw client; |
+ SchedulerClientThatSetNeedsCommitInsideDraw client; |
SchedulerSettings default_scheduler_settings; |
Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
+ EXPECT_FALSE(client.needs_begin_frame()); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
EXPECT_EQ(0, client.num_draws()); |
EXPECT_TRUE(client.needs_begin_frame()); |
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()); |
+ |
+ scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_FALSE(client.needs_begin_frame()); |
} |
@@ -544,7 +662,8 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
client.SetDrawWillHappen(false); |
@@ -555,6 +674,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 |
@@ -565,6 +685,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()); |
@@ -573,6 +694,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()); |
@@ -580,13 +702,14 @@ TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
} |
TEST(SchedulerTest, NoSwapWhenDrawFails) { |
- SchedulerClientThatsetNeedsCommitInsideDraw client; |
+ SchedulerClientThatSetNeedsCommitInsideDraw client; |
SchedulerSettings default_scheduler_settings; |
Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
scheduler->SetCanStart(); |
scheduler->SetVisible(true); |
scheduler->SetCanDraw(true); |
- scheduler->DidCreateAndInitializeOutputSurface(); |
+ InitializeOutputSurfaceAndFirstCommit(scheduler); |
+ client.Reset(); |
scheduler->SetNeedsRedraw(); |
EXPECT_TRUE(scheduler->RedrawPending()); |
@@ -595,6 +718,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { |
// Draw successfully, this starts a new frame. |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(1, client.num_draws()); |
scheduler->SetNeedsRedraw(); |
@@ -604,6 +728,7 @@ TEST(SchedulerTest, NoSwapWhenDrawFails) { |
// Fail to draw, this should not start a frame. |
client.SetDrawWillHappen(false); |
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
+ scheduler->OnBeginFrameDeadline(); |
EXPECT_EQ(2, client.num_draws()); |
} |
@@ -616,11 +741,37 @@ TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) { |
client.SetDrawWillHappen(true); |
client.SetSwapWillHappenIfDrawHappens(false); |
- // Get the compositor to do a ScheduledActionDrawAndSwapForced. |
+ // Get the compositor to do a ScheduledActionDrawAndReadback. |
+ scheduler->SetCanDraw(true); |
+ scheduler->SetNeedsRedraw(); |
+ scheduler->SetNeedsForcedCommitForReadback(); |
+ scheduler->FinishCommit(); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
+} |
+ |
+TEST(SchedulerTest, BackToBackReadbackAllowed) { |
+ // Some clients call readbacks twice in a row before the replacement |
+ // commit comes in. Make sure it is allowed. |
+ FakeSchedulerClient client; |
+ SchedulerSettings default_scheduler_settings; |
+ Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
+ |
+ // Get the compositor to do 2 ScheduledActionDrawAndReadbacks before |
+ // the replacement commit comes in. |
scheduler->SetCanDraw(true); |
scheduler->SetNeedsRedraw(); |
- scheduler->SetNeedsForcedRedraw(); |
- EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapForced")); |
+ scheduler->SetNeedsForcedCommitForReadback(); |
+ scheduler->FinishCommit(); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
+ |
+ client.Reset(); |
+ scheduler->SetNeedsForcedCommitForReadback(); |
+ scheduler->FinishCommit(); |
+ EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
+ |
+ // The replacement commit comes in after 2 readbacks. |
+ client.Reset(); |
+ scheduler->FinishCommit(); |
} |
} // namespace |