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