Title: [100055] trunk/Source
Revision
100055
Author
[email protected]
Date
2011-11-11 18:05:39 -0800 (Fri, 11 Nov 2011)

Log Message

[chromium] Fix CCThreadProxy::setVisible
https://bugs.webkit.org/show_bug.cgi?id=71903

The behavior is different depending on whether we're showing
or hiding the compositor. This patch fixes both code paths.

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

* platform/graphics/chromium/cc/CCCompletionEvent.h:
(WebCore::CCCompletionEvent::CCCompletionEvent):
(WebCore::CCCompletionEvent::~CCCompletionEvent):
(WebCore::CCCompletionEvent::wait):
(WebCore::CCCompletionEvent::signal):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::setVisible):

Modified Paths

Diff

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


--- trunk/Source/WebCore/ChangeLog	2011-11-12 01:52:27 UTC (rev 100054)
+++ trunk/Source/WebCore/ChangeLog	2011-11-12 02:05:39 UTC (rev 100055)
@@ -1,5 +1,23 @@
 2011-11-11  Iain Merrick  <[email protected]>
 
+        [chromium] Fix CCThreadProxy::setVisible
+        https://bugs.webkit.org/show_bug.cgi?id=71903
+
+        The behavior is different depending on whether we're showing
+        or hiding the compositor. This patch fixes both code paths.
+
+        Reviewed by James Robinson.
+
+        * platform/graphics/chromium/cc/CCCompletionEvent.h:
+        (WebCore::CCCompletionEvent::CCCompletionEvent):
+        (WebCore::CCCompletionEvent::~CCCompletionEvent):
+        (WebCore::CCCompletionEvent::wait):
+        (WebCore::CCCompletionEvent::signal):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::setVisible):
+
+2011-11-11  Iain Merrick  <[email protected]>
+
         [chromium] CCThreadProxy::finishAllRendering hangs if !visible
         https://bugs.webkit.org/show_bug.cgi?id=71920
 

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


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h	2011-11-12 01:52:27 UTC (rev 100054)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCCompletionEvent.h	2011-11-12 02:05:39 UTC (rev 100055)
@@ -30,35 +30,54 @@
 namespace WebCore {
 
 // Used for making blocking calls from one thread to another. Use only when
-// absolutely certain that doing-so will not lead to a livelock.
+// absolutely certain that doing-so will not lead to a deadlock.
 //
 // It is safe to destroy this object as soon as wait() returns.
 class CCCompletionEvent {
 public:
     CCCompletionEvent()
     {
+#ifndef NDEBUG
+        m_waited = false;
+        m_signaled = false;
+#endif
         m_mutex.lock();
     }
 
     ~CCCompletionEvent()
     {
         m_mutex.unlock();
+        ASSERT(m_waited);
+        ASSERT(m_signaled);
     }
 
     void wait()
     {
+        ASSERT(!m_waited);
+#ifndef NDEBUG
+        m_waited = true;
+#endif
         m_condition.wait(m_mutex);
     }
 
     void signal()
     {
         MutexLocker lock(m_mutex);
+        ASSERT(!m_signaled);
+#ifndef NDEBUG
+        m_signaled = true;
+#endif
         m_condition.signal();
     }
 
 private:
     Mutex m_mutex;
     ThreadCondition m_condition;
+#ifndef NDEBUG
+    // Used to assert that wait() and signal() are each called exactly once.
+    bool m_waited;
+    bool m_signaled;
+#endif
 };
 
 }

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


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2011-11-12 01:52:27 UTC (rev 100054)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp	2011-11-12 02:05:39 UTC (rev 100055)
@@ -249,20 +249,20 @@
 void CCThreadProxy::setVisible(bool visible)
 {
     ASSERT(isMainThread());
-    if (!visible) {
-        CCCompletionEvent completion;
-        s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::didBecomeInvisibleOnImplThread, AllowCrossThreadAccess(&completion)));
-        return;
-    }
-    setNeedsRedraw();
+    CCCompletionEvent completion;
+    s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::setVisibleOnImplThread, AllowCrossThreadAccess(&completion), visible));
+    completion.wait();
 }
 
-void CCThreadProxy::didBecomeInvisibleOnImplThread(CCCompletionEvent* completion)
+void CCThreadProxy::setVisibleOnImplThread(CCCompletionEvent* completion, bool visible)
 {
     ASSERT(isImplThread());
-    m_layerTreeHost->didBecomeInvisibleOnImplThread(m_layerTreeHostImpl.get());
-    m_schedulerOnImplThread->setVisible(false);
-    m_layerTreeHostImpl->setVisible(false);
+    if (!visible)
+        m_layerTreeHost->didBecomeInvisibleOnImplThread(m_layerTreeHostImpl.get());
+    else
+        m_schedulerOnImplThread->setNeedsRedraw();
+    m_schedulerOnImplThread->setVisible(visible);
+    m_layerTreeHostImpl->setVisible(visible);
     completion->signal();
 }
 
@@ -447,8 +447,6 @@
 
     m_layerTreeHost->beginCommitOnImplThread(m_layerTreeHostImpl.get());
     CCTextureUpdater updater(m_layerTreeHostImpl->contentsTextureAllocator());
-    m_layerTreeHostImpl->setVisible(m_layerTreeHost->visible());
-    m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());
     m_layerTreeHost->finishCommitOnImplThread(m_layerTreeHostImpl.get());
 
     m_layerTreeHostImpl->commitComplete();

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


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h	2011-11-12 01:52:27 UTC (rev 100054)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h	2011-11-12 02:05:39 UTC (rev 100055)
@@ -99,7 +99,7 @@
     void initializeImplOnImplThread(CCCompletionEvent*);
     void initializeLayerRendererOnImplThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*, int* compositorIdentifier);
     void setNeedsAnimateOnImplThread();
-    void didBecomeInvisibleOnImplThread(CCCompletionEvent*);
+    void setVisibleOnImplThread(CCCompletionEvent*, bool visible);
     void layerTreeHostClosedOnImplThread(CCCompletionEvent*);
 
     // Accessed on main thread only.

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (100054 => 100055)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2011-11-12 01:52:27 UTC (rev 100054)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2011-11-12 02:05:39 UTC (rev 100055)
@@ -209,6 +209,11 @@
         callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsRedraw, this);
     }
 
+    void postSetVisibleToMainThread(bool visible)
+    {
+        callOnMainThread(visible ? CCLayerTreeHostTest::dispatchSetVisible : CCLayerTreeHostTest::dispatchSetInvisible, this);
+    }
+
     void timeout()
     {
         m_timedOut = true;
@@ -271,6 +276,24 @@
           test->m_layerTreeHost->setNeedsRedraw();
     }
 
+    static void dispatchSetVisible(void* self)
+    {
+      ASSERT(isMainThread());
+      CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+      ASSERT(test);
+      if (test->m_layerTreeHost)
+          test->m_layerTreeHost->setVisible(true);
+    }
+
+    static void dispatchSetInvisible(void* self)
+    {
+      ASSERT(isMainThread());
+      CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+      ASSERT(test);
+      if (test->m_layerTreeHost)
+          test->m_layerTreeHost->setVisible(false);
+    }
+
     class TimeoutTask : public webkit_support::TaskAdaptor {
     public:
         explicit TimeoutTask(CCLayerTreeHostTest* test)
@@ -764,4 +787,42 @@
     runTestThreaded();
 }
 
+class CCLayerTreeHostTestSetVisible : public CCLayerTreeHostTest {
+public:
+
+    CCLayerTreeHostTestSetVisible()
+        : m_numCommits(0)
+        , m_numDraws(0)
+    {
+    }
+
+    virtual void beginTest()
+    {
+        postSetVisibleToMainThread(false);
+        postSetNeedsRedrawToMainThread(); // This is suppressed while we're invisible.
+        postSetVisibleToMainThread(true); // Triggers the redraw.
+    }
+
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
+    {
+        EXPECT_TRUE(impl->visible());
+        ++m_numDraws;
+        endTest();
+    }
+
+    virtual void afterTest()
+    {
+        EXPECT_EQ(1, m_numDraws);
+    }
+
+private:
+    int m_numCommits;
+    int m_numDraws;
+};
+
+TEST_F(CCLayerTreeHostTestSetVisible, runMultiThread)
+{
+    runTest(true);
+}
+
 } // namespace
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to