Title: [120634] trunk/Source
Revision
120634
Author
[email protected]
Date
2012-06-18 15:17:30 -0700 (Mon, 18 Jun 2012)

Log Message

[chromium] Ensure that skipping frames during an accelerated animation doesn't cause starvation
https://bugs.webkit.org/show_bug.cgi?id=87766

Patch by Ian Vollick <[email protected]> on 2012-06-18
Reviewed by James Robinson.

Source/WebCore:

Unit tests:
    CCLayerTreeHostTestCheckerboardDoesNotStarveDraws.runMultiThread
    CCSchedulerStateMachineTest.TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit

* platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
(WebCore::CCSchedulerStateMachine::CCSchedulerStateMachine):
(WebCore::CCSchedulerStateMachine::updateState):
(WebCore::CCSchedulerStateMachine::didDrawIfPossibleCompleted):
(WebCore::CCSchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced):
(WebCore):
* platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
(CCSchedulerStateMachine):

Source/WebKit/chromium:

* tests/CCLayerTreeHostTest.cpp:
(WTF):
(CCLayerTreeHostTestCheckerboardDoesNotStarveDraws):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::beginTest):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::afterTest):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::animateLayers):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::drawLayersOnCCThread):
(WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::prepareToDrawOnCCThread):
(WTF::TEST_F):
* tests/CCSchedulerStateMachineTest.cpp:
(WebCore::TEST):
(WebCore):
* tests/CCThreadedTest.cpp:
(WebKitTests::MockLayerTreeHostImpl::prepareToDraw):
* tests/CCThreadedTest.h:
(WebKitTests::TestHooks::prepareToDrawOnCCThread):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (120633 => 120634)


--- trunk/Source/WebCore/ChangeLog	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebCore/ChangeLog	2012-06-18 22:17:30 UTC (rev 120634)
@@ -1,3 +1,23 @@
+2012-06-18  Ian Vollick  <[email protected]>
+
+        [chromium] Ensure that skipping frames during an accelerated animation doesn't cause starvation
+        https://bugs.webkit.org/show_bug.cgi?id=87766
+
+        Reviewed by James Robinson.
+
+        Unit tests:
+            CCLayerTreeHostTestCheckerboardDoesNotStarveDraws.runMultiThread
+            CCSchedulerStateMachineTest.TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit
+
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
+        (WebCore::CCSchedulerStateMachine::CCSchedulerStateMachine):
+        (WebCore::CCSchedulerStateMachine::updateState):
+        (WebCore::CCSchedulerStateMachine::didDrawIfPossibleCompleted):
+        (WebCore::CCSchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
+        (CCSchedulerStateMachine):
+
 2012-06-18  Nico Weber  <[email protected]>
 
         [chromium/mac] Unbreak smooth scrolling.

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp (120633 => 120634)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp	2012-06-18 22:17:30 UTC (rev 120634)
@@ -32,8 +32,11 @@
     : m_commitState(COMMIT_STATE_IDLE)
     , m_currentFrameNumber(0)
     , m_lastFrameNumberWhereDrawWasCalled(-1)
+    , m_consecutiveFailedDraws(0)
+    , m_maximumNumberOfFailedDrawsBeforeDrawIsForced(3)
     , m_needsRedraw(false)
     , m_needsForcedRedraw(false)
+    , m_needsForcedRedrawAfterNextCommit(false)
     , m_needsCommit(false)
     , m_needsForcedCommit(false)
     , m_mainThreadNeedsLayerTextures(false)
@@ -177,9 +180,16 @@
             m_commitState = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
         else
             m_commitState = COMMIT_STATE_IDLE;
+
         m_needsRedraw = true;
         if (m_drawIfPossibleFailed)
             m_lastFrameNumberWhereDrawWasCalled = -1;
+
+        if (m_needsForcedRedrawAfterNextCommit) {
+            m_needsForcedRedrawAfterNextCommit = false;
+            m_needsForcedRedraw = true;
+        }
+
         m_textureState = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
         return;
 
@@ -262,7 +272,15 @@
     if (m_drawIfPossibleFailed) {
         m_needsRedraw = true;
         m_needsCommit = true;
-    }
+        m_consecutiveFailedDraws++;
+        if (m_consecutiveFailedDraws >= m_maximumNumberOfFailedDrawsBeforeDrawIsForced) {
+            m_consecutiveFailedDraws = 0;
+            // We need to force a draw, but it doesn't make sense to do this until
+            // we've committed and have new textures.
+            m_needsForcedRedrawAfterNextCommit = true;
+        }
+    } else
+      m_consecutiveFailedDraws = 0;
 }
 
 void CCSchedulerStateMachine::setNeedsCommit()
@@ -304,4 +322,9 @@
     setNeedsCommit();
 }
 
+void CCSchedulerStateMachine::setMaximumNumberOfFailedDrawsBeforeDrawIsForced(int numDraws)
+{
+    m_maximumNumberOfFailedDrawsBeforeDrawIsForced = numDraws;
 }
+
+}

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h (120633 => 120634)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h	2012-06-18 22:17:30 UTC (rev 120634)
@@ -141,6 +141,9 @@
     void didLoseContext();
     void didRecreateContext();
 
+    // Exposed for testing purposes.
+    void setMaximumNumberOfFailedDrawsBeforeDrawIsForced(int);
+
 protected:
     bool shouldDrawForced() const;
     bool drawSuspendedUntilCommit() const;
@@ -153,8 +156,11 @@
 
     int m_currentFrameNumber;
     int m_lastFrameNumberWhereDrawWasCalled;
+    int m_consecutiveFailedDraws;
+    int m_maximumNumberOfFailedDrawsBeforeDrawIsForced;
     bool m_needsRedraw;
     bool m_needsForcedRedraw;
+    bool m_needsForcedRedrawAfterNextCommit;
     bool m_needsCommit;
     bool m_needsForcedCommit;
     bool m_mainThreadNeedsLayerTextures;

Modified: trunk/Source/WebKit/chromium/ChangeLog (120633 => 120634)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-06-18 22:17:30 UTC (rev 120634)
@@ -1,3 +1,28 @@
+2012-06-18  Ian Vollick  <[email protected]>
+
+        [chromium] Ensure that skipping frames during an accelerated animation doesn't cause starvation
+        https://bugs.webkit.org/show_bug.cgi?id=87766
+
+        Reviewed by James Robinson.
+
+        * tests/CCLayerTreeHostTest.cpp:
+        (WTF):
+        (CCLayerTreeHostTestCheckerboardDoesNotStarveDraws):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::beginTest):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::afterTest):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::animateLayers):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::drawLayersOnCCThread):
+        (WTF::CCLayerTreeHostTestCheckerboardDoesNotStarveDraws::prepareToDrawOnCCThread):
+        (WTF::TEST_F):
+        * tests/CCSchedulerStateMachineTest.cpp:
+        (WebCore::TEST):
+        (WebCore):
+        * tests/CCThreadedTest.cpp:
+        (WebKitTests::MockLayerTreeHostImpl::prepareToDraw):
+        * tests/CCThreadedTest.h:
+        (WebKitTests::TestHooks::prepareToDrawOnCCThread):
+
 2012-06-18  Xianzhu Wang  <[email protected]>
 
         [Chromium] Change back "linuxish" to "linux" and include WebFontRendering.cpp on Android

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (120633 => 120634)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-06-18 22:17:30 UTC (rev 120634)
@@ -582,6 +582,50 @@
     runTestThreaded();
 }
 
+// Add a layer animation to a layer, but continually fail to draw. Confirm that after
+// a while, we do eventually force a draw.
+class CCLayerTreeHostTestCheckerboardDoesNotStarveDraws : public CCLayerTreeHostTestThreadOnly {
+public:
+    CCLayerTreeHostTestCheckerboardDoesNotStarveDraws()
+        : m_startedAnimating(false)
+    {
+    }
+
+    virtual void beginTest()
+    {
+        postAddAnimationToMainThread();
+    }
+
+    virtual void afterTest()
+    {
+    }
+
+    virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
+    {
+        m_startedAnimating = true;
+    }
+
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*)
+    {
+        if (m_startedAnimating)
+            endTest();
+    }
+
+    virtual bool prepareToDrawOnCCThread(CCLayerTreeHostImpl*)
+    {
+        return false;
+    }
+
+private:
+    bool m_startedAnimating;
+};
+
+// Starvation can only be an issue with the MT compositor.
+TEST_F(CCLayerTreeHostTestCheckerboardDoesNotStarveDraws, runMultiThread)
+{
+    runTestThreaded();
+}
+
 // Ensures that animations continue to be ticked when we are backgrounded.
 class CCLayerTreeHostTestTickAnimationWhileBackgrounded : public CCLayerTreeHostTestThreadOnly {
 public:

Modified: trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp (120633 => 120634)


--- trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp	2012-06-18 22:17:30 UTC (rev 120634)
@@ -285,6 +285,48 @@
     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
 }
 
+TEST(CCSchedulerStateMachineTest, TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit)
+{
+    CCSchedulerStateMachine state;
+    state.setCanBeginFrame(true);
+    state.setVisible(true);
+    state.setMaximumNumberOfFailedDrawsBeforeDrawIsForced(1);
+
+    // Start a commit.
+    state.setNeedsCommit();
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
+    state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_FRAME);
+    EXPECT_TRUE(state.commitPending());
+
+    // Then initiate a draw.
+    state.setNeedsRedraw();
+    EXPECT_TRUE(state.vsyncCallbackNeeded());
+    state.didEnterVSync();
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
+    EXPECT_TRUE(state.redrawPending());
+
+    // Fail the draw.
+    state.updateState(CCSchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
+    state.didDrawIfPossibleCompleted(false);
+    EXPECT_TRUE(state.redrawPending());
+    // But the commit is ongoing.
+    EXPECT_TRUE(state.commitPending());
+
+    // Finish the commit. Note, we should not yet be forcing a draw, but should
+    // continue the commit as usual.
+    state.beginFrameComplete();
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
+    state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
+    state.beginUpdateMoreResourcesComplete(false);
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
+    state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
+    EXPECT_TRUE(state.redrawPending());
+
+    // The redraw should be forced in this case.
+    EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
+}
+
 TEST(CCSchedulerStateMachineTest, TestFailedDrawIsRetriedNextVSync)
 {
     CCSchedulerStateMachine state;

Modified: trunk/Source/WebKit/chromium/tests/CCThreadedTest.cpp (120633 => 120634)


--- trunk/Source/WebKit/chromium/tests/CCThreadedTest.cpp	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebKit/chromium/tests/CCThreadedTest.cpp	2012-06-18 22:17:30 UTC (rev 120634)
@@ -133,7 +133,8 @@
 bool MockLayerTreeHostImpl::prepareToDraw(FrameData& frame)
 {
     bool result = CCLayerTreeHostImpl::prepareToDraw(frame);
-    m_testHooks->prepareToDrawOnCCThread(this);
+    if (!m_testHooks->prepareToDrawOnCCThread(this))
+        result = false;
     return result;
 }
 

Modified: trunk/Source/WebKit/chromium/tests/CCThreadedTest.h (120633 => 120634)


--- trunk/Source/WebKit/chromium/tests/CCThreadedTest.h	2012-06-18 22:16:36 UTC (rev 120633)
+++ trunk/Source/WebKit/chromium/tests/CCThreadedTest.h	2012-06-18 22:17:30 UTC (rev 120634)
@@ -51,7 +51,7 @@
 public:
     virtual void beginCommitOnCCThread(WebCore::CCLayerTreeHostImpl*) { }
     virtual void commitCompleteOnCCThread(WebCore::CCLayerTreeHostImpl*) { }
-    virtual void prepareToDrawOnCCThread(WebCore::CCLayerTreeHostImpl*) { }
+    virtual bool prepareToDrawOnCCThread(WebCore::CCLayerTreeHostImpl*) { return true; }
     virtual void drawLayersOnCCThread(WebCore::CCLayerTreeHostImpl*) { }
     virtual void animateLayers(WebCore::CCLayerTreeHostImpl*, double monotonicTime) { }
     virtual void willAnimateLayers(WebCore::CCLayerTreeHostImpl*, double monotonicTime) { }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to