summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/tests/CCSchedulerTest.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/tests/CCSchedulerTest.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit/chromium/tests/CCSchedulerTest.cpp')
-rw-r--r--Source/WebKit/chromium/tests/CCSchedulerTest.cpp316
1 files changed, 279 insertions, 37 deletions
diff --git a/Source/WebKit/chromium/tests/CCSchedulerTest.cpp b/Source/WebKit/chromium/tests/CCSchedulerTest.cpp
index 45f61b90b..41250884b 100644
--- a/Source/WebKit/chromium/tests/CCSchedulerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCSchedulerTest.cpp
@@ -45,25 +45,56 @@ public:
m_actions.clear();
m_hasMoreResourceUpdates = false;
m_canDraw = true;
+ m_drawWillHappen = true;
+ m_swapWillHappenIfDrawHappens = true;
+ m_numDraws = 0;
}
void setHasMoreResourceUpdates(bool b) { m_hasMoreResourceUpdates = b; }
void setCanDraw(bool b) { m_canDraw = b; }
+ int numDraws() const { return m_numDraws; }
int numActions() const { return static_cast<int>(m_actions.size()); }
const char* action(int i) const { return m_actions[i]; }
- virtual bool canDraw() { return m_canDraw; }
- virtual bool hasMoreResourceUpdates() const { return m_hasMoreResourceUpdates; }
- virtual void scheduledActionBeginFrame() { m_actions.push_back("scheduledActionBeginFrame"); }
- virtual void scheduledActionDrawAndSwap() { m_actions.push_back("scheduledActionDrawAndSwap"); }
- virtual void scheduledActionUpdateMoreResources() { m_actions.push_back("scheduledActionUpdateMoreResources"); }
- virtual void scheduledActionCommit() { m_actions.push_back("scheduledActionCommit"); }
- virtual void scheduledActionBeginContextRecreation() { m_actions.push_back("scheduledActionBeginContextRecreation"); }
+ bool hasAction(const char* action) const
+ {
+ for (size_t i = 0; i < m_actions.size(); i++)
+ if (!strcmp(m_actions[i], action))
+ return true;
+ return false;
+ }
+
+ virtual bool canDraw() OVERRIDE { return m_canDraw; }
+ virtual bool hasMoreResourceUpdates() const OVERRIDE { return m_hasMoreResourceUpdates; }
+ virtual void scheduledActionBeginFrame() OVERRIDE { m_actions.push_back("scheduledActionBeginFrame"); }
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE
+ {
+ m_actions.push_back("scheduledActionDrawAndSwapIfPossible");
+ m_numDraws++;
+ return CCScheduledActionDrawAndSwapResult(m_drawWillHappen, m_drawWillHappen && m_swapWillHappenIfDrawHappens);
+ }
+
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE
+ {
+ m_actions.push_back("scheduledActionDrawAndSwapForced");
+ return CCScheduledActionDrawAndSwapResult(true, m_swapWillHappenIfDrawHappens);
+ }
+
+ virtual void scheduledActionUpdateMoreResources() OVERRIDE { m_actions.push_back("scheduledActionUpdateMoreResources"); }
+ virtual void scheduledActionCommit() OVERRIDE { m_actions.push_back("scheduledActionCommit"); }
+ virtual void scheduledActionBeginContextRecreation() OVERRIDE { m_actions.push_back("scheduledActionBeginContextRecreation"); }
+ virtual void scheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { m_actions.push_back("scheduledActionAcquireLayerTexturesForMainThread"); }
+
+ void setDrawWillHappen(bool drawWillHappen) { m_drawWillHappen = drawWillHappen; }
+ void setSwapWillHappenIfDrawHappens(bool swapWillHappenIfDrawHappens) { m_swapWillHappenIfDrawHappens = swapWillHappenIfDrawHappens; }
protected:
bool m_hasMoreResourceUpdates;
bool m_canDraw;
+ bool m_drawWillHappen;
+ bool m_swapWillHappenIfDrawHappens;
+ int m_numDraws;
std::vector<const char*> m_actions;
};
@@ -72,6 +103,7 @@ TEST(CCSchedulerTest, RequestCommit)
FakeCCSchedulerClient client;
RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ scheduler->setCanBeginFrame(true);
scheduler->setVisible(true);
// SetNeedsCommit should begin the frame.
@@ -94,7 +126,7 @@ TEST(CCSchedulerTest, RequestCommit)
// Tick should draw.
timeSource->tick();
EXPECT_EQ(1, client.numActions());
- EXPECT_STREQ("scheduledActionDrawAndSwap", client.action(0));
+ EXPECT_STREQ("scheduledActionDrawAndSwapIfPossible", client.action(0));
EXPECT_FALSE(timeSource->active());
client.reset();
@@ -107,6 +139,7 @@ TEST(CCSchedulerTest, RequestCommitAfterBeginFrame)
FakeCCSchedulerClient client;
RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ scheduler->setCanBeginFrame(true);
scheduler->setVisible(true);
// SetNedsCommit should begin the frame.
@@ -131,38 +164,104 @@ TEST(CCSchedulerTest, RequestCommitAfterBeginFrame)
timeSource->tick();
EXPECT_FALSE(timeSource->active());
EXPECT_EQ(2, client.numActions());
- EXPECT_STREQ("scheduledActionDrawAndSwap", client.action(0));
+ EXPECT_STREQ("scheduledActionDrawAndSwapIfPossible", client.action(0));
EXPECT_STREQ("scheduledActionBeginFrame", client.action(1));
client.reset();
}
-class SchedulerClientThatSetNeedsDrawInsideDraw : public CCSchedulerClient {
+TEST(CCSchedulerTest, TextureAcquisitionCollision)
+{
+ FakeCCSchedulerClient client;
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ scheduler->setCanBeginFrame(true);
+ scheduler->setVisible(true);
+
+ scheduler->setNeedsCommit();
+ scheduler->setMainThreadNeedsLayerTextures();
+ EXPECT_EQ(2, client.numActions());
+ EXPECT_STREQ("scheduledActionBeginFrame", client.action(0));
+ EXPECT_STREQ("scheduledActionAcquireLayerTexturesForMainThread", client.action(1));
+ client.reset();
+
+ // Compositor not scheduled to draw because textures are locked by main thread
+ EXPECT_FALSE(timeSource->active());
+
+ // Trigger the commit
+ scheduler->beginFrameComplete();
+ EXPECT_TRUE(timeSource->active());
+ client.reset();
+
+ // Between commit and draw, texture acquisition for main thread delayed,
+ // and main thread blocks.
+ scheduler->setMainThreadNeedsLayerTextures();
+ EXPECT_EQ(0, client.numActions());
+ client.reset();
+
+ // Once compositor draw complete, the delayed texture acquisition fires.
+ timeSource->tick();
+ EXPECT_EQ(3, client.numActions());
+ EXPECT_STREQ("scheduledActionDrawAndSwapIfPossible", client.action(0));
+ EXPECT_STREQ("scheduledActionAcquireLayerTexturesForMainThread", client.action(1));
+ EXPECT_STREQ("scheduledActionBeginFrame", client.action(2));
+ client.reset();
+}
+
+TEST(CCSchedulerTest, VisibilitySwitchWithTextureAcquisition)
+{
+ FakeCCSchedulerClient client;
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ scheduler->setCanBeginFrame(true);
+ scheduler->setVisible(true);
+
+ scheduler->setNeedsCommit();
+ scheduler->beginFrameComplete();
+ scheduler->setMainThreadNeedsLayerTextures();
+ client.reset();
+ // Verify that pending texture acquisition fires when visibility
+ // is lost in order to avoid a deadlock.
+ scheduler->setVisible(false);
+ EXPECT_EQ(1, client.numActions());
+ EXPECT_STREQ("scheduledActionAcquireLayerTexturesForMainThread", client.action(0));
+ client.reset();
+
+ // 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.
+ scheduler->setVisible(true);
+ EXPECT_EQ(1, client.numActions());
+ EXPECT_STREQ("scheduledActionBeginFrame", client.action(0));
+ client.reset();
+}
+
+class SchedulerClientThatSetNeedsDrawInsideDraw : public FakeCCSchedulerClient {
public:
SchedulerClientThatSetNeedsDrawInsideDraw()
- : m_numDraws(0)
- , m_scheduler(0) { }
+ : m_scheduler(0) { }
void setScheduler(CCScheduler* scheduler) { m_scheduler = scheduler; }
- int numDraws() const { return m_numDraws; }
-
- virtual bool hasMoreResourceUpdates() const { return false; }
- virtual bool canDraw() { return true; }
- virtual void scheduledActionBeginFrame() { }
- virtual void scheduledActionDrawAndSwap()
+ virtual void scheduledActionBeginFrame() OVERRIDE { }
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE
{
// Only setNeedsRedraw the first time this is called
if (!m_numDraws)
m_scheduler->setNeedsRedraw();
- m_numDraws++;
+ return FakeCCSchedulerClient::scheduledActionDrawAndSwapIfPossible();
}
- virtual void scheduledActionUpdateMoreResources() { }
- virtual void scheduledActionCommit() { }
- virtual void scheduledActionBeginContextRecreation() { }
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE
+ {
+ ASSERT_NOT_REACHED();
+ return CCScheduledActionDrawAndSwapResult(true, true);
+ }
+
+ virtual void scheduledActionUpdateMoreResources() OVERRIDE { }
+ virtual void scheduledActionCommit() OVERRIDE { }
+ virtual void scheduledActionBeginContextRecreation() OVERRIDE { }
protected:
- int m_numDraws;
CCScheduler* m_scheduler;
};
@@ -176,6 +275,7 @@ TEST(CCSchedulerTest, RequestRedrawInsideDraw)
RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
client.setScheduler(scheduler.get());
+ scheduler->setCanBeginFrame(true);
scheduler->setVisible(true);
scheduler->setNeedsRedraw();
@@ -194,33 +294,74 @@ TEST(CCSchedulerTest, RequestRedrawInsideDraw)
EXPECT_FALSE(timeSource->active());
}
-class SchedulerClientThatSetNeedsCommitInsideDraw : public CCSchedulerClient {
+// Test that requesting redraw inside a failed draw doesn't lose the request.
+TEST(CCSchedulerTest, RequestRedrawInsideFailedDraw)
+{
+ SchedulerClientThatSetNeedsDrawInsideDraw client;
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ client.setScheduler(scheduler.get());
+ scheduler->setCanBeginFrame(true);
+ scheduler->setVisible(true);
+ client.setDrawWillHappen(false);
+
+ scheduler->setNeedsRedraw();
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+ EXPECT_EQ(0, client.numDraws());
+
+ // Fail the draw.
+ timeSource->tick();
+ EXPECT_EQ(1, client.numDraws());
+
+ // We have a commit pending and the draw failed, and we didn't lose the redraw request.
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+
+ // Fail the draw again.
+ timeSource->tick();
+ EXPECT_EQ(2, client.numDraws());
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+
+ // Draw successfully.
+ client.setDrawWillHappen(true);
+ timeSource->tick();
+ EXPECT_EQ(3, client.numDraws());
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_FALSE(scheduler->redrawPending());
+ EXPECT_FALSE(timeSource->active());
+}
+
+class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeCCSchedulerClient {
public:
SchedulerClientThatSetNeedsCommitInsideDraw()
- : m_numDraws(0)
- , m_scheduler(0) { }
+ : m_scheduler(0) { }
void setScheduler(CCScheduler* scheduler) { m_scheduler = scheduler; }
- int numDraws() const { return m_numDraws; }
-
- virtual bool hasMoreResourceUpdates() const { return false; }
- virtual bool canDraw() { return true; }
- virtual void scheduledActionBeginFrame() { }
- virtual void scheduledActionDrawAndSwap()
+ virtual void scheduledActionBeginFrame() OVERRIDE { }
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapIfPossible() OVERRIDE
{
// Only setNeedsCommit the first time this is called
if (!m_numDraws)
m_scheduler->setNeedsCommit();
- m_numDraws++;
+ return FakeCCSchedulerClient::scheduledActionDrawAndSwapIfPossible();
+ }
+
+ virtual CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapForced() OVERRIDE
+ {
+ ASSERT_NOT_REACHED();
+ return CCScheduledActionDrawAndSwapResult(true, true);
}
- virtual void scheduledActionUpdateMoreResources() { }
- virtual void scheduledActionCommit() { }
- virtual void scheduledActionBeginContextRecreation() { }
+ virtual void scheduledActionUpdateMoreResources() OVERRIDE { }
+ virtual void scheduledActionCommit() OVERRIDE { }
+ virtual void scheduledActionBeginContextRecreation() OVERRIDE { }
protected:
- int m_numDraws;
CCScheduler* m_scheduler;
};
@@ -232,6 +373,7 @@ TEST(CCSchedulerTest, RequestCommitInsideDraw)
RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
client.setScheduler(scheduler.get());
+ scheduler->setCanBeginFrame(true);
scheduler->setVisible(true);
scheduler->setNeedsRedraw();
@@ -251,4 +393,104 @@ TEST(CCSchedulerTest, RequestCommitInsideDraw)
EXPECT_FALSE(scheduler->redrawPending());
}
+// Tests that when a draw fails then the pending commit should not be dropped.
+TEST(CCSchedulerTest, RequestCommitInsideFailedDraw)
+{
+ SchedulerClientThatSetNeedsDrawInsideDraw client;
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, adoptPtr(new CCFrameRateController(timeSource)));
+ client.setScheduler(scheduler.get());
+ scheduler->setCanBeginFrame(true);
+ scheduler->setVisible(true);
+ client.setDrawWillHappen(false);
+
+ scheduler->setNeedsRedraw();
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+ EXPECT_EQ(0, client.numDraws());
+
+ // Fail the draw.
+ timeSource->tick();
+ EXPECT_EQ(1, client.numDraws());
+
+ // We have a commit pending and the draw failed, and we didn't lose the commit request.
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+
+ // Fail the draw again.
+ timeSource->tick();
+ EXPECT_EQ(2, client.numDraws());
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+
+ // Draw successfully.
+ client.setDrawWillHappen(true);
+ timeSource->tick();
+ EXPECT_EQ(3, client.numDraws());
+ EXPECT_TRUE(scheduler->commitPending());
+ EXPECT_FALSE(scheduler->redrawPending());
+ EXPECT_FALSE(timeSource->active());
+}
+
+TEST(CCSchedulerTest, NoBeginFrameWhenDrawFails)
+{
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ SchedulerClientThatSetNeedsCommitInsideDraw client;
+ OwnPtr<FakeCCFrameRateController> controller = adoptPtr(new FakeCCFrameRateController(timeSource));
+ FakeCCFrameRateController* controllerPtr = controller.get();
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, controller.release());
+ client.setScheduler(scheduler.get());
+ scheduler->setCanBeginFrame(true);
+ scheduler->setVisible(true);
+
+ EXPECT_EQ(0, controllerPtr->numFramesPending());
+
+ scheduler->setNeedsRedraw();
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+ EXPECT_EQ(0, client.numDraws());
+
+ // Draw successfully, this starts a new frame.
+ timeSource->tick();
+ EXPECT_EQ(1, client.numDraws());
+ EXPECT_EQ(1, controllerPtr->numFramesPending());
+ scheduler->didSwapBuffersComplete();
+ EXPECT_EQ(0, controllerPtr->numFramesPending());
+
+ scheduler->setNeedsRedraw();
+ EXPECT_TRUE(scheduler->redrawPending());
+ EXPECT_TRUE(timeSource->active());
+
+ // Fail to draw, this should not start a frame.
+ client.setDrawWillHappen(false);
+ timeSource->tick();
+ EXPECT_EQ(2, client.numDraws());
+ EXPECT_EQ(0, controllerPtr->numFramesPending());
+}
+
+TEST(CCSchedulerTest, NoBeginFrameWhenSwapFailsDuringForcedCommit)
+{
+ RefPtr<FakeCCTimeSource> timeSource = adoptRef(new FakeCCTimeSource());
+ FakeCCSchedulerClient client;
+ OwnPtr<FakeCCFrameRateController> controller = adoptPtr(new FakeCCFrameRateController(timeSource));
+ FakeCCFrameRateController* controllerPtr = controller.get();
+ OwnPtr<CCScheduler> scheduler = CCScheduler::create(&client, controller.release());
+
+ EXPECT_EQ(0, controllerPtr->numFramesPending());
+
+ // Tell the client that it will fail to swap.
+ client.setDrawWillHappen(true);
+ client.setSwapWillHappenIfDrawHappens(false);
+
+ // Get the compositor to do a scheduledActionDrawAndSwapForced.
+ scheduler->setNeedsRedraw();
+ scheduler->setNeedsForcedRedraw();
+ EXPECT_TRUE(client.hasAction("scheduledActionDrawAndSwapForced"));
+
+ // We should not have told the frame rate controller that we began a frame.
+ EXPECT_EQ(0, controllerPtr->numFramesPending());
+}
+
}