<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[203718] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/203718">203718</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-26 06:26:35 -0700 (Tue, 26 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Threaded Compositor] Crashes and deadlocks in single web process mode
https://bugs.webkit.org/show_bug.cgi?id=160160

Reviewed by Žan Doberšek.

Every WebPage has its own threaded compositor that runs its own compositing thread. That means that when there's
more than one WebPage in the same process, we are running OpenGL stuff in different secondary threads. That's
causing crashes and deadlocks in X and graphics drivers. We should ensure there's a single compositing thread
per process when multiple threads is not supported. This is causing unit test
WebKit2.WKPageGetScaleFactorNotZero to time out since we switched to the threaded compositor. That test is
creating two pages in the same web process, and most of the times the web process crashes or deadlocks causing
the test to never finish and time out.
This patch makes CompositingRunLoop use a thread pool that spawns the compositing threads and schedules the tasks
there.

* Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:
(WebKit::WorkQueuePool::singleton):
(WebKit::WorkQueuePool::dispatch):
(WebKit::WorkQueuePool::runLoop):
(WebKit::WorkQueuePool::invalidate):
(WebKit::WorkQueuePool::WorkQueuePool):
(WebKit::WorkQueuePool::getOrCreateWorkQueueForContext):
(WebKit::CompositingRunLoop::CompositingRunLoop):
(WebKit::CompositingRunLoop::~CompositingRunLoop):
(WebKit::CompositingRunLoop::performTask):
(WebKit::CompositingRunLoop::performTaskSync):
* Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:
* Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
(WebKit::ThreadedCompositor::ThreadedCompositor):
(WebKit::ThreadedCompositor::invalidate):
(WebKit::ThreadedCompositor::setNativeSurfaceHandleForCompositing):
(WebKit::ThreadedCompositor::setDeviceScaleFactor):
(WebKit::ThreadedCompositor::setDrawsBackground):
(WebKit::ThreadedCompositor::didChangeViewportSize):
(WebKit::ThreadedCompositor::didChangeViewportAttribute):
(WebKit::ThreadedCompositor::didChangeContentsSize):
(WebKit::ThreadedCompositor::scrollTo):
(WebKit::ThreadedCompositor::scrollBy):
(WebKit::ThreadedCompositor::purgeBackingStores):
(WebKit::ThreadedCompositor::renderNextFrame):
(WebKit::ThreadedCompositor::commitScrollOffset):
(WebKit::ThreadedCompositor::updateViewport):
(WebKit::ThreadedCompositor::scheduleDisplayImmediately):
(WebKit::ThreadedCompositor::forceRepaint):
(WebKit::ThreadedCompositor::tryEnsureGLContext): Deleted.
(WebKit::ThreadedCompositor::glContext): Deleted.
(WebKit::ThreadedCompositor::updateSceneState): Deleted.
* Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorCompositingRunLoopcpp">trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorCompositingRunLooph">trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h</a></li>
<li><a href="#trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorcpp">trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorh">trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (203717 => 203718)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/ChangeLog        2016-07-26 13:26:35 UTC (rev 203718)
</span><span class="lines">@@ -1,3 +1,54 @@
</span><ins>+2016-07-26  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [Threaded Compositor] Crashes and deadlocks in single web process mode
+        https://bugs.webkit.org/show_bug.cgi?id=160160
+
+        Reviewed by Žan Doberšek.
+
+        Every WebPage has its own threaded compositor that runs its own compositing thread. That means that when there's
+        more than one WebPage in the same process, we are running OpenGL stuff in different secondary threads. That's
+        causing crashes and deadlocks in X and graphics drivers. We should ensure there's a single compositing thread
+        per process when multiple threads is not supported. This is causing unit test
+        WebKit2.WKPageGetScaleFactorNotZero to time out since we switched to the threaded compositor. That test is
+        creating two pages in the same web process, and most of the times the web process crashes or deadlocks causing
+        the test to never finish and time out.
+        This patch makes CompositingRunLoop use a thread pool that spawns the compositing threads and schedules the tasks
+        there.
+
+        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:
+        (WebKit::WorkQueuePool::singleton):
+        (WebKit::WorkQueuePool::dispatch):
+        (WebKit::WorkQueuePool::runLoop):
+        (WebKit::WorkQueuePool::invalidate):
+        (WebKit::WorkQueuePool::WorkQueuePool):
+        (WebKit::WorkQueuePool::getOrCreateWorkQueueForContext):
+        (WebKit::CompositingRunLoop::CompositingRunLoop):
+        (WebKit::CompositingRunLoop::~CompositingRunLoop):
+        (WebKit::CompositingRunLoop::performTask):
+        (WebKit::CompositingRunLoop::performTaskSync):
+        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:
+        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
+        (WebKit::ThreadedCompositor::ThreadedCompositor):
+        (WebKit::ThreadedCompositor::invalidate):
+        (WebKit::ThreadedCompositor::setNativeSurfaceHandleForCompositing):
+        (WebKit::ThreadedCompositor::setDeviceScaleFactor):
+        (WebKit::ThreadedCompositor::setDrawsBackground):
+        (WebKit::ThreadedCompositor::didChangeViewportSize):
+        (WebKit::ThreadedCompositor::didChangeViewportAttribute):
+        (WebKit::ThreadedCompositor::didChangeContentsSize):
+        (WebKit::ThreadedCompositor::scrollTo):
+        (WebKit::ThreadedCompositor::scrollBy):
+        (WebKit::ThreadedCompositor::purgeBackingStores):
+        (WebKit::ThreadedCompositor::renderNextFrame):
+        (WebKit::ThreadedCompositor::commitScrollOffset):
+        (WebKit::ThreadedCompositor::updateViewport):
+        (WebKit::ThreadedCompositor::scheduleDisplayImmediately):
+        (WebKit::ThreadedCompositor::forceRepaint):
+        (WebKit::ThreadedCompositor::tryEnsureGLContext): Deleted.
+        (WebKit::ThreadedCompositor::glContext): Deleted.
+        (WebKit::ThreadedCompositor::updateSceneState): Deleted.
+        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
+
</ins><span class="cx"> 2016-07-25  Sam Weinig  &lt;sam@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix assertion.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorCompositingRunLoopcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp (203717 => 203718)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp        2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp        2016-07-26 13:26:35 UTC (rev 203718)
</span><span class="lines">@@ -28,22 +28,97 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(COORDINATED_GRAPHICS_THREADED)
</span><span class="cx"> 
</span><del>-#include &lt;wtf/CurrentTime.h&gt;
</del><ins>+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><ins>+#include &lt;wtf/NeverDestroyed.h&gt;
+#include &lt;wtf/WorkQueue.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><ins>+class WorkQueuePool {
+    WTF_MAKE_NONCOPYABLE(WorkQueuePool);
+    friend class NeverDestroyed&lt;WorkQueuePool&gt;;
+public:
+    static WorkQueuePool&amp; singleton()
+    {
+        ASSERT(isMainThread());
+        static NeverDestroyed&lt;WorkQueuePool&gt; workQueuePool;
+        return workQueuePool;
+    }
+
+    void dispatch(void* context, Function&lt;void ()&gt;&amp;&amp; function)
+    {
+        ASSERT(isMainThread());
+        getOrCreateWorkQueueForContext(context).dispatch(WTFMove(function));
+    }
+
+    RunLoop&amp; runLoop(void* context)
+    {
+        return getOrCreateWorkQueueForContext(context).runLoop();
+    }
+
+    void invalidate(void* context)
+    {
+        auto workQueue = m_workQueueMap.take(context);
+        RELEASE_ASSERT(workQueue);
+        if (m_workQueueMap.isEmpty()) {
+            m_sharedWorkQueue = nullptr;
+            m_threadCount = 0;
+        } else if (workQueue-&gt;hasOneRef())
+            m_threadCount--;
+    }
+
+private:
+    WorkQueuePool()
+    {
+#if PLATFORM(GTK)
+        m_threadCountLimit = 1;
+#else
+        m_threadCountLimit = std::numeric_limits&lt;unsigned&gt;::max();
+#endif
+    }
+
+    WorkQueue&amp; getOrCreateWorkQueueForContext(void* context)
+    {
+        auto addResult = m_workQueueMap.add(context, nullptr);
+        if (addResult.isNewEntry) {
+            // FIXME: This is OK for now, and it works for a single-thread limit. But for configurations where more (but not unlimited)
+            // threads could be used, one option would be to use a HashSet here and disperse the contexts across the available threads.
+            if (m_threadCount &gt;= m_threadCountLimit) {
+                RELEASE_ASSERT(m_sharedWorkQueue);
+                addResult.iterator-&gt;value = m_sharedWorkQueue;
+            } else {
+                addResult.iterator-&gt;value = WorkQueue::create(&quot;org.webkit.ThreadedCompositorWorkQueue&quot;);
+                if (!m_threadCount)
+                    m_sharedWorkQueue = addResult.iterator-&gt;value;
+                m_threadCount++;
+            }
+        }
+
+        return *addResult.iterator-&gt;value;
+    }
+
+    HashMap&lt;void*, RefPtr&lt;WorkQueue&gt;&gt; m_workQueueMap;
+    RefPtr&lt;WorkQueue&gt; m_sharedWorkQueue;
+    unsigned m_threadCount { 0 };
+    unsigned m_threadCountLimit;
+};
+
</ins><span class="cx"> CompositingRunLoop::CompositingRunLoop(std::function&lt;void ()&gt;&amp;&amp; updateFunction)
</span><del>-    : m_runLoop(RunLoop::current())
-    , m_updateTimer(m_runLoop, this, &amp;CompositingRunLoop::updateTimerFired)
</del><ins>+    : m_updateTimer(WorkQueuePool::singleton().runLoop(this), this, &amp;CompositingRunLoop::updateTimerFired)
</ins><span class="cx">     , m_updateFunction(WTFMove(updateFunction))
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CompositingRunLoop::~CompositingRunLoop()
+{
+    WorkQueuePool::singleton().invalidate(this);
+}
+
</ins><span class="cx"> void CompositingRunLoop::performTask(Function&lt;void ()&gt;&amp;&amp; function)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    m_runLoop.dispatch(WTFMove(function));
</del><ins>+    WorkQueuePool::singleton().dispatch(this, WTFMove(function));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CompositingRunLoop::performTaskSync(Function&lt;void ()&gt;&amp;&amp; function)
</span><span class="lines">@@ -50,9 +125,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     LockHolder locker(m_dispatchSyncConditionMutex);
</span><del>-    m_runLoop.dispatch([this, function = WTFMove(function)] {
</del><ins>+    WorkQueuePool::singleton().dispatch(this, [this, function = WTFMove(function)] {
+        function();
</ins><span class="cx">         LockHolder locker(m_dispatchSyncConditionMutex);
</span><del>-        function();
</del><span class="cx">         m_dispatchSyncCondition.notifyOne();
</span><span class="cx">     });
</span><span class="cx">     m_dispatchSyncCondition.wait(m_dispatchSyncConditionMutex);
</span><span class="lines">@@ -82,17 +157,6 @@
</span><span class="cx">     m_lastUpdateTime = monotonicallyIncreasingTime();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CompositingRunLoop::run()
-{
-    m_runLoop.run();
-}
-
-void CompositingRunLoop::stop()
-{
-    m_updateTimer.stop();
-    m_runLoop.stop();
-}
-
</del><span class="cx"> } // namespace WebKit
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(COORDINATED_GRAPHICS_THREADED)
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorCompositingRunLooph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h (203717 => 203718)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h        2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h        2016-07-26 13:26:35 UTC (rev 203718)
</span><span class="lines">@@ -28,8 +28,9 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(COORDINATED_GRAPHICS_THREADED)
</span><span class="cx"> 
</span><del>-#include &lt;functional&gt;
-#include &lt;wtf/FastMalloc.h&gt;
</del><ins>+#include &lt;wtf/Condition.h&gt;
+#include &lt;wtf/Function.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/RunLoop.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -37,7 +38,6 @@
</span><span class="cx"> 
</span><span class="cx"> class CompositingRunLoop {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(CompositingRunLoop);
</span><del>-    WTF_MAKE_FAST_ALLOCATED;
</del><span class="cx"> public:
</span><span class="cx">     enum UpdateTiming {
</span><span class="cx">         Immediate,
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     CompositingRunLoop(std::function&lt;void ()&gt;&amp;&amp;);
</span><ins>+    ~CompositingRunLoop();
</ins><span class="cx"> 
</span><span class="cx">     void performTask(Function&lt;void ()&gt;&amp;&amp;);
</span><span class="cx">     void performTaskSync(Function&lt;void ()&gt;&amp;&amp;);
</span><span class="lines">@@ -52,13 +53,9 @@
</span><span class="cx">     void startUpdateTimer(UpdateTiming = Immediate);
</span><span class="cx">     void stopUpdateTimer();
</span><span class="cx"> 
</span><del>-    void run();
-    void stop();
-
</del><span class="cx"> private:
</span><span class="cx">     void updateTimerFired();
</span><span class="cx"> 
</span><del>-    RunLoop&amp; m_runLoop;
</del><span class="cx">     RunLoop::Timer&lt;CompositingRunLoop&gt; m_updateTimer;
</span><span class="cx">     std::function&lt;void ()&gt; m_updateFunction;
</span><span class="cx">     Lock m_dispatchSyncConditionMutex;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp (203717 => 203718)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp        2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp        2016-07-26 13:26:35 UTC (rev 203718)
</span><span class="lines">@@ -30,8 +30,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CompositingRunLoop.h&quot;
</span><span class="cx"> #include &lt;WebCore/TransformationMatrix.h&gt;
</span><del>-#include &lt;wtf/RunLoop.h&gt;
-#include &lt;wtf/StdLibExtras.h&gt;
</del><span class="cx"> 
</span><span class="cx"> #if USE(OPENGL_ES_2)
</span><span class="cx"> #include &lt;GLES2/gl2.h&gt;
</span><span class="lines">@@ -50,8 +48,12 @@
</span><span class="cx"> 
</span><span class="cx"> ThreadedCompositor::ThreadedCompositor(Client* client)
</span><span class="cx">     : m_client(client)
</span><ins>+    , m_compositingRunLoop([this] { renderLayerTree(); })
</ins><span class="cx"> {
</span><del>-    createCompositingThread();
</del><ins>+    m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
+        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
+        m_viewportController = std::make_unique&lt;SimpleViewportController&gt;(this);
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ThreadedCompositor::~ThreadedCompositor()
</span><span class="lines">@@ -61,14 +63,20 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::invalidate()
</span><span class="cx"> {
</span><del>-    terminateCompositingThread();
</del><ins>+    m_scene-&gt;detach();
+    m_compositingRunLoop.stopUpdateTimer();
+    m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
+        m_context = nullptr;
+        m_scene = nullptr;
+        m_viewportController = nullptr;
+    });
</ins><span class="cx">     m_client = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::setNativeSurfaceHandleForCompositing(uint64_t handle)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;stopUpdateTimer();
-    m_compositingRunLoop-&gt;performTaskSync([this, protectedThis = makeRef(*this), handle] {
</del><ins>+    m_compositingRunLoop.stopUpdateTimer();
+    m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this), handle] {
</ins><span class="cx">         m_scene-&gt;setActive(!!handle);
</span><span class="cx"> 
</span><span class="cx">         // A new native handle can't be set without destroying the previous one first if any.
</span><span class="lines">@@ -81,7 +89,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::setDeviceScaleFactor(float scale)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = makeRef(*this), scale] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), scale] {
</ins><span class="cx">         m_deviceScaleFactor = scale;
</span><span class="cx">         scheduleDisplayImmediately();
</span><span class="cx">     });
</span><span class="lines">@@ -89,7 +97,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::setDrawsBackground(bool drawsBackground)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = Ref&lt;ThreadedCompositor&gt;(*this), drawsBackground] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = Ref&lt;ThreadedCompositor&gt;(*this), drawsBackground] {
</ins><span class="cx">         m_drawsBackground = drawsBackground;
</span><span class="cx">         scheduleDisplayImmediately();
</span><span class="cx">     });
</span><span class="lines">@@ -97,7 +105,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::didChangeViewportSize(const IntSize&amp; size)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTaskSync([this, protectedThis = makeRef(*this), size] {
</del><ins>+    m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this), size] {
</ins><span class="cx">         m_viewportController-&gt;didChangeViewportSize(size);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -104,7 +112,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::didChangeViewportAttribute(const ViewportAttributes&amp; attr)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = makeRef(*this), attr] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), attr] {
</ins><span class="cx">         m_viewportController-&gt;didChangeViewportAttribute(attr);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -111,7 +119,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::didChangeContentsSize(const IntSize&amp; size)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = makeRef(*this), size] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), size] {
</ins><span class="cx">         m_viewportController-&gt;didChangeContentsSize(size);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -118,7 +126,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::scrollTo(const IntPoint&amp; position)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = makeRef(*this), position] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), position] {
</ins><span class="cx">         m_viewportController-&gt;scrollTo(position);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -125,7 +133,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::scrollBy(const IntSize&amp; delta)
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTask([this, protectedThis = makeRef(*this), delta] {
</del><ins>+    m_compositingRunLoop.performTask([this, protectedThis = makeRef(*this), delta] {
</ins><span class="cx">         m_viewportController-&gt;scrollBy(delta);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -132,22 +140,30 @@
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::purgeBackingStores()
</span><span class="cx"> {
</span><ins>+    ASSERT(isMainThread());
</ins><span class="cx">     m_client-&gt;purgeBackingStores();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ThreadedCompositor::renderNextFrame()
</span><span class="cx"> {
</span><ins>+    ASSERT(isMainThread());
</ins><span class="cx">     m_client-&gt;renderNextFrame();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ThreadedCompositor::commitScrollOffset(uint32_t layerID, const IntSize&amp; offset)
+{
+    ASSERT(isMainThread());
+    m_client-&gt;commitScrollOffset(layerID, offset);
+}
+
</ins><span class="cx"> void ThreadedCompositor::updateViewport()
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;startUpdateTimer(CompositingRunLoop::WaitUntilNextFrame);
</del><ins>+    m_compositingRunLoop.startUpdateTimer(CompositingRunLoop::WaitUntilNextFrame);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThreadedCompositor::commitScrollOffset(uint32_t layerID, const IntSize&amp; offset)
</del><ins>+void ThreadedCompositor::scheduleDisplayImmediately()
</ins><span class="cx"> {
</span><del>-    m_client-&gt;commitScrollOffset(layerID, offset);
</del><ins>+    m_compositingRunLoop.startUpdateTimer(CompositingRunLoop::Immediate);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ThreadedCompositor::tryEnsureGLContext()
</span><span class="lines">@@ -180,14 +196,9 @@
</span><span class="cx">     return m_context.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThreadedCompositor::scheduleDisplayImmediately()
-{
-    m_compositingRunLoop-&gt;startUpdateTimer(CompositingRunLoop::Immediate);
-}
-
</del><span class="cx"> void ThreadedCompositor::forceRepaint()
</span><span class="cx"> {
</span><del>-    m_compositingRunLoop-&gt;performTaskSync([this, protectedThis = makeRef(*this)] {
</del><ins>+    m_compositingRunLoop.performTaskSync([this, protectedThis = makeRef(*this)] {
</ins><span class="cx">         renderLayerTree();
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -237,55 +248,5 @@
</span><span class="cx">     scheduleDisplayImmediately();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ThreadedCompositor::createCompositingThread()
-{
-    if (m_threadIdentifier)
-        return;
-
-    LockHolder locker(m_initializeRunLoopConditionMutex);
-    m_threadIdentifier = createThread(&quot;WebKit: ThreadedCompositor&quot;, [this] { runCompositingThread(); });
-    m_initializeRunLoopCondition.wait(m_initializeRunLoopConditionMutex);
</del><span class="cx"> }
</span><del>-
-void ThreadedCompositor::runCompositingThread()
-{
-    {
-        LockHolder locker(m_initializeRunLoopConditionMutex);
-
-        m_compositingRunLoop = std::make_unique&lt;CompositingRunLoop&gt;([&amp;] {
-            renderLayerTree();
-        });
-        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
-        m_viewportController = std::make_unique&lt;SimpleViewportController&gt;(this);
-
-        m_initializeRunLoopCondition.notifyOne();
-    }
-
-    m_compositingRunLoop-&gt;run();
-
-    m_scene-&gt;purgeGLResources();
-
-    {
-        LockHolder locker(m_terminateRunLoopConditionMutex);
-        m_context = nullptr;
-        m_scene = nullptr;
-        m_viewportController = nullptr;
-        m_compositingRunLoop = nullptr;
-        m_terminateRunLoopCondition.notifyOne();
-    }
-
-    detachThread(m_threadIdentifier);
-}
-
-void ThreadedCompositor::terminateCompositingThread()
-{
-    LockHolder locker(m_terminateRunLoopConditionMutex);
-
-    m_scene-&gt;detach();
-    m_compositingRunLoop-&gt;stop();
-
-    m_terminateRunLoopCondition.wait(m_terminateRunLoopConditionMutex);
-}
-
-}
</del><span class="cx"> #endif // USE(COORDINATED_GRAPHICS_THREADED)
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h (203717 => 203718)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h        2016-07-26 11:08:28 UTC (rev 203717)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h        2016-07-26 13:26:35 UTC (rev 203718)
</span><span class="lines">@@ -28,16 +28,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(COORDINATED_GRAPHICS_THREADED)
</span><span class="cx"> 
</span><ins>+#include &quot;CompositingRunLoop.h&quot;
</ins><span class="cx"> #include &quot;CoordinatedGraphicsScene.h&quot;
</span><span class="cx"> #include &quot;SimpleViewportController.h&quot;
</span><span class="cx"> #include &lt;WebCore/GLContext.h&gt;
</span><span class="cx"> #include &lt;WebCore/IntSize.h&gt;
</span><del>-#include &lt;WebCore/TransformationMatrix.h&gt;
-#include &lt;wtf/Condition.h&gt;
</del><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><del>-#include &lt;wtf/Threading.h&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> struct CoordinatedGraphicsState;
</span><span class="lines">@@ -45,7 +43,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span><del>-class CompositingRunLoop;
</del><span class="cx"> class CoordinatedGraphicsScene;
</span><span class="cx"> class CoordinatedGraphicsSceneClient;
</span><span class="cx"> 
</span><span class="lines">@@ -89,22 +86,18 @@
</span><span class="cx">     void updateViewport() override;
</span><span class="cx">     void commitScrollOffset(uint32_t layerID, const WebCore::IntSize&amp; offset) override;
</span><span class="cx"> 
</span><ins>+    // SimpleViewportController::Client.
+    void didChangeVisibleRect() override;
+
</ins><span class="cx">     void renderLayerTree();
</span><span class="cx">     void scheduleDisplayImmediately();
</span><del>-    void didChangeVisibleRect() override;
</del><span class="cx"> 
</span><span class="cx">     bool tryEnsureGLContext();
</span><span class="cx">     WebCore::GLContext* glContext();
</span><span class="cx"> 
</span><del>-    void createCompositingThread();
-    void runCompositingThread();
-    void terminateCompositingThread();
-    static void compositingThreadEntry(void*);
-
-    Client* m_client;
</del><ins>+    Client* m_client { nullptr };
</ins><span class="cx">     RefPtr&lt;CoordinatedGraphicsScene&gt; m_scene;
</span><span class="cx">     std::unique_ptr&lt;SimpleViewportController&gt; m_viewportController;
</span><del>-
</del><span class="cx">     std::unique_ptr&lt;WebCore::GLContext&gt; m_context;
</span><span class="cx"> 
</span><span class="cx">     WebCore::IntSize m_viewportSize;
</span><span class="lines">@@ -112,13 +105,7 @@
</span><span class="cx">     bool m_drawsBackground { true };
</span><span class="cx">     uint64_t m_nativeSurfaceHandle { 0 };
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;CompositingRunLoop&gt; m_compositingRunLoop;
-
-    ThreadIdentifier m_threadIdentifier { 0 };
-    Condition m_initializeRunLoopCondition;
-    Lock m_initializeRunLoopConditionMutex;
-    Condition m_terminateRunLoopCondition;
-    Lock m_terminateRunLoopConditionMutex;
</del><ins>+    CompositingRunLoop m_compositingRunLoop;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre>
</div>
</div>

</body>
</html>