| 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
|
|
|