Title: [100054] trunk/Source
Revision
100054
Author
[email protected]
Date
2011-11-11 17:52:27 -0800 (Fri, 11 Nov 2011)

Log Message

[chromium] CCThreadProxy::finishAllRendering hangs if !visible
https://bugs.webkit.org/show_bug.cgi?id=71920

Patch by Iain Merrick <[email protected]> on 2011-11-11
Reviewed by James Robinson.

Source/WebCore:

* platform/graphics/chromium/cc/CCScheduler.cpp:
(WebCore::CCScheduler::setNeedsForcedRedraw):
* platform/graphics/chromium/cc/CCScheduler.h:
* platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
(WebCore::CCSchedulerStateMachine::CCSchedulerStateMachine):
(WebCore::CCSchedulerStateMachine::nextAction):
(WebCore::CCSchedulerStateMachine::updateState):
(WebCore::CCSchedulerStateMachine::setNeedsForcedRedraw):
* platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::requestReadbackOnImplThread):
(WebCore::CCThreadProxy::finishAllRenderingOnImplThread):

Source/WebKit/chromium:

* tests/CCSchedulerStateMachineTest.cpp:
(WebCore::TEST):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (100053 => 100054)


--- trunk/Source/WebCore/ChangeLog	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/ChangeLog	2011-11-12 01:52:27 UTC (rev 100054)
@@ -1,3 +1,23 @@
+2011-11-11  Iain Merrick  <[email protected]>
+
+        [chromium] CCThreadProxy::finishAllRendering hangs if !visible
+        https://bugs.webkit.org/show_bug.cgi?id=71920
+
+        Reviewed by James Robinson.
+
+        * platform/graphics/chromium/cc/CCScheduler.cpp:
+        (WebCore::CCScheduler::setNeedsForcedRedraw):
+        * platform/graphics/chromium/cc/CCScheduler.h:
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp:
+        (WebCore::CCSchedulerStateMachine::CCSchedulerStateMachine):
+        (WebCore::CCSchedulerStateMachine::nextAction):
+        (WebCore::CCSchedulerStateMachine::updateState):
+        (WebCore::CCSchedulerStateMachine::setNeedsForcedRedraw):
+        * platform/graphics/chromium/cc/CCSchedulerStateMachine.h:
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::requestReadbackOnImplThread):
+        (WebCore::CCThreadProxy::finishAllRenderingOnImplThread):
+
 2011-11-11  John Knottenbelt  <[email protected]>
 
         [Chromium] Enable building without shared workers.

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp (100053 => 100054)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.cpp	2011-11-12 01:52:27 UTC (rev 100054)
@@ -68,6 +68,12 @@
     processScheduledActions();
 }
 
+void CCScheduler::setNeedsForcedRedraw()
+{
+    m_stateMachine.setNeedsForcedRedraw();
+    processScheduledActions();
+}
+
 void CCScheduler::beginFrameComplete()
 {
     TRACE_EVENT("CCScheduler::beginFrameComplete", this, 0);

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h (100053 => 100054)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCScheduler.h	2011-11-12 01:52:27 UTC (rev 100054)
@@ -64,6 +64,9 @@
     void setNeedsCommit();
     void setNeedsRedraw();
 
+    // As setNeedsRedraw(), but ensures the draw will definitely happen even if we are not visible.
+    void setNeedsForcedRedraw();
+
     void beginFrameComplete();
 
     void setMaxFramesPending(int);

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


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.cpp	2011-11-12 01:52:27 UTC (rev 100054)
@@ -31,6 +31,7 @@
 CCSchedulerStateMachine::CCSchedulerStateMachine()
     : m_commitState(COMMIT_STATE_IDLE)
     , m_needsRedraw(false)
+    , m_needsForcedRedraw(false)
     , m_needsCommit(false)
     , m_updateMoreResourcesPending(false)
     , m_insideVSync(false)
@@ -38,21 +39,22 @@
 
 CCSchedulerStateMachine::Action CCSchedulerStateMachine::nextAction() const
 {
+    bool shouldDraw = (m_needsRedraw && m_insideVSync && m_visible) || m_needsForcedRedraw;
     switch (m_commitState) {
     case COMMIT_STATE_IDLE:
-        if (m_needsRedraw && m_insideVSync && m_visible)
+        if (shouldDraw)
             return ACTION_DRAW;
         if (m_needsCommit && m_visible)
             return ACTION_BEGIN_FRAME;
         return ACTION_NONE;
 
     case COMMIT_STATE_FRAME_IN_PROGRESS:
-        if (m_needsRedraw && m_insideVSync && m_visible)
+        if (shouldDraw)
             return ACTION_DRAW;
         return ACTION_NONE;
 
     case COMMIT_STATE_UPDATING_RESOURCES:
-        if (m_needsRedraw && m_insideVSync && m_visible)
+        if (shouldDraw)
             return ACTION_DRAW;
         if (!m_updateMoreResourcesPending)
             return ACTION_BEGIN_UPDATE_MORE_RESOURCES;
@@ -62,7 +64,7 @@
         return ACTION_COMMIT;
 
     case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
-        if (m_needsRedraw && m_insideVSync && m_visible)
+        if (shouldDraw)
             return ACTION_DRAW;
         return ACTION_NONE;
     }
@@ -97,6 +99,7 @@
 
     case ACTION_DRAW:
         m_needsRedraw = false;
+        m_needsForcedRedraw = false;
         if (m_commitState == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
             ASSERT(m_needsCommit);
             m_commitState = COMMIT_STATE_IDLE;
@@ -120,6 +123,11 @@
     m_needsRedraw = true;
 }
 
+void CCSchedulerStateMachine::setNeedsForcedRedraw()
+{
+    m_needsForcedRedraw = true;
+}
+
 void CCSchedulerStateMachine::setNeedsCommit()
 {
     m_needsCommit = true;

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


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSchedulerStateMachine.h	2011-11-12 01:52:27 UTC (rev 100054)
@@ -78,6 +78,10 @@
     // or the screen being damaged and simply needing redisplay.
     void setNeedsRedraw();
 
+    // As setNeedsRedraw(), but ensures the draw will definitely happen even if
+    // we are not visible.
+    void setNeedsForcedRedraw();
+
     // Indicates that a new commit flow needs to be performed, either to pull
     // updates from the main thread to the impl, or to push deltas from the impl
     // thread to main.
@@ -89,13 +93,14 @@
     void beginFrameComplete();
 
     // Call this only in response to receiving an ACTION_UPDATE_MORE_RESOURCES
-    // from nextState. Indicatest that the specific update request completed.
+    // from nextState. Indicates that the specific update request completed.
     void beginUpdateMoreResourcesComplete(bool morePending);
 
 protected:
     CommitState m_commitState;
 
     bool m_needsRedraw;
+    bool m_needsForcedRedraw;
     bool m_needsCommit;
     bool m_updateMoreResourcesPending;
     bool m_insideVSync;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp (100053 => 100054)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2011-11-12 01:52:27 UTC (rev 100054)
@@ -128,7 +128,7 @@
         return;
     }
     m_readbackRequestOnImplThread = request;
-    m_schedulerOnImplThread->setNeedsRedraw();
+    m_schedulerOnImplThread->setNeedsForcedRedraw();
 }
 
 GraphicsContext3D* CCThreadProxy::context()
@@ -308,8 +308,9 @@
     TRACE_EVENT("CCThreadProxy::finishAllRenderingOnImplThread", this, 0);
     ASSERT(isImplThread());
     ASSERT(!m_finishAllRenderingCompletionEventOnImplThread);
-    m_schedulerOnImplThread->setNeedsRedraw();
     m_finishAllRenderingCompletionEventOnImplThread = completion;
+
+    m_schedulerOnImplThread->setNeedsForcedRedraw();
 }
 
 void CCThreadProxy::scheduledActionBeginFrame()

Modified: trunk/Source/WebKit/chromium/ChangeLog (100053 => 100054)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-11-12 01:52:27 UTC (rev 100054)
@@ -1,3 +1,13 @@
+2011-11-11  Iain Merrick  <[email protected]>
+
+        [chromium] CCThreadProxy::finishAllRendering hangs if !visible
+        https://bugs.webkit.org/show_bug.cgi?id=71920
+
+        Reviewed by James Robinson.
+
+        * tests/CCSchedulerStateMachineTest.cpp:
+        (WebCore::TEST):
+
 2011-11-11  Antoine Labour  <[email protected]>
 
         [chromium] Add translation/scaling to WebExternalTextureLayer

Modified: trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp (100053 => 100054)


--- trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp	2011-11-12 01:38:02 UTC (rev 100053)
+++ trunk/Source/WebKit/chromium/tests/CCSchedulerStateMachineTest.cpp	2011-11-12 01:52:27 UTC (rev 100054)
@@ -55,6 +55,9 @@
     void setNeedsRedraw(bool b) { m_needsRedraw = b; }
     bool needsRedraw() const { return m_needsRedraw; }
 
+    void setNeedsForcedRedraw(bool b) { m_needsForcedRedraw = b; }
+    bool needsForcedRedraw() const { return m_needsForcedRedraw; }
+
     bool insideVSync() const { return m_insideVSync; }
     bool visible() const { return m_visible; }
 
@@ -99,103 +102,124 @@
     }
 }
 
+TEST(CCSchedulerStateMachineTest, TestSetForcedRedrawDoesNotSetsNormalRedraw)
+{
+    CCSchedulerStateMachine state;
+    state.setNeedsForcedRedraw();
+    EXPECT_FALSE(state.redrawPending());
+}
+
 TEST(CCSchedulerStateMachineTest, TestNextActionDrawsOnVSync)
 {
-    // When not on vsync, don't draw.
+    // When not on vsync, or on vsync but not visible, don't draw.
     size_t numCommitStates = sizeof(allCommitStates) / sizeof(CCSchedulerStateMachine::CommitState);
     for (size_t i = 0; i < numCommitStates; ++i) {
-        StateMachine state;
-        state.setCommitState(allCommitStates[i]);
-        state.setNeedsRedraw(true);
-        state.setVisible(true);
-        state.setInsideVSync(false);
+        for (unsigned j = 0; j < 2; ++j) {
+            StateMachine state;
+            state.setCommitState(allCommitStates[i]);
+            if (!j) {
+                state.setInsideVSync(true);
+                state.setVisible(false);
+            } else
+                state.setInsideVSync(false);
 
-        // Case 1: needsCommit=false updateMoreResourcesPending=false.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 1: needsCommit=false updateMoreResourcesPending=false.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
 
-        // Case 2: needsCommit=false updateMoreResourcesPending=true.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 2: needsCommit=false updateMoreResourcesPending=true.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
 
-        // Case 3: needsCommit=true updateMoreResourcesPending=false.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 3: needsCommit=true updateMoreResourcesPending=false.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
 
-        // Case 4: needsCommit=true updateMoreResourcesPending=true.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 4: needsCommit=true updateMoreResourcesPending=true.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+        }
     }
 
-    // When on vsync, you should always draw. Expect if you're ready to commit, in which case commit.
+    // When on vsync, or not on vsync but needsForcedRedraw set, should always draw expect if you're ready to commit, in which case commit.
     for (size_t i = 0; i < numCommitStates; ++i) {
-        StateMachine state;
-        state.setCommitState(allCommitStates[i]);
-        state.setNeedsRedraw(true);
-        state.setVisible(true);
-        state.setInsideVSync(true);
-        CCSchedulerStateMachine::Action expectedAction;
-        if (allCommitStates[i] != CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT)
-            expectedAction = CCSchedulerStateMachine::ACTION_DRAW;
-        else
-            expectedAction = CCSchedulerStateMachine::ACTION_COMMIT;
+        for (unsigned j = 0; j < 2; ++j) {
+            StateMachine state;
+            state.setCommitState(allCommitStates[i]);
+            if (!j) {
+                state.setInsideVSync(true);
+                state.setNeedsRedraw(true);
+                state.setVisible(true);
+            } else
+                state.setNeedsForcedRedraw(true);
 
-        // Case 1: needsCommit=false updateMoreResourcesPending=false.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_EQ(expectedAction, state.nextAction());
+            CCSchedulerStateMachine::Action expectedAction;
+            if (allCommitStates[i] != CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT)
+                expectedAction = CCSchedulerStateMachine::ACTION_DRAW;
+            else
+                expectedAction = CCSchedulerStateMachine::ACTION_COMMIT;
 
-        // Case 2: needsCommit=false updateMoreResourcesPending=true.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_EQ(expectedAction, state.nextAction());
+            // Case 1: needsCommit=false updateMoreResourcesPending=false.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_EQ(expectedAction, state.nextAction());
 
-        // Case 3: needsCommit=true updateMoreResourcesPending=false.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_EQ(expectedAction, state.nextAction());
+            // Case 2: needsCommit=false updateMoreResourcesPending=true.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_EQ(expectedAction, state.nextAction());
 
-        // Case 4: needsCommit=true updateMoreResourcesPending=true.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_EQ(expectedAction, state.nextAction());
+            // Case 3: needsCommit=true updateMoreResourcesPending=false.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_EQ(expectedAction, state.nextAction());
+
+            // Case 4: needsCommit=true updateMoreResourcesPending=true.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_EQ(expectedAction, state.nextAction());
+        }
     }
 }
 
 TEST(CCSchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible)
 {
-    // If not visible, never redraw.
     size_t numCommitStates = sizeof(allCommitStates) / sizeof(CCSchedulerStateMachine::CommitState);
     for (size_t i = 0; i < numCommitStates; ++i) {
         StateMachine state;
         state.setCommitState(allCommitStates[i]);
+        state.setVisible(false);
         state.setNeedsRedraw(true);
-        state.setInsideVSync(false);
-        state.setVisible(false);
+        state.setNeedsForcedRedraw(false);
 
-        // Case 1: needsCommit=false updateMoreResourcesPending=false.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+        // There shouldn't be any drawing regardless of vsync.
+        for (unsigned j = 0; j < 2; ++j) {
+            state.setInsideVSync(j == 1);
 
-        // Case 2: needsCommit=false updateMoreResourcesPending=true.
-        state.setNeedsCommit(false);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 1: needsCommit=false updateMoreResourcesPending=false.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
 
-        // Case 3: needsCommit=true updateMoreResourcesPending=false.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(false);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 2: needsCommit=false updateMoreResourcesPending=true.
+            state.setNeedsCommit(false);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
 
-        // Case 4: needsCommit=true updateMoreResourcesPending=true.
-        state.setNeedsCommit(true);
-        state.setUpdateMoreResourcesPending(true);
-        EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+            // Case 3: needsCommit=true updateMoreResourcesPending=false.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(false);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+
+            // Case 4: needsCommit=true updateMoreResourcesPending=true.
+            state.setNeedsCommit(true);
+            state.setUpdateMoreResourcesPending(true);
+            EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
+        }
     }
 }
 
@@ -216,7 +240,7 @@
     // Begin an update.
     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
 
-    // Veriify we don't do anything, both for vsync and not vsync.
+    // Verify we don't do anything, both for vsync and not vsync.
     state.setInsideVSync(false);
     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
     state.setInsideVSync(true);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to