<!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>[203504] 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/203504">203504</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-21 09:02:52 -0700 (Thu, 21 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GTK][Threaded Compositor] WTR generates fully white images for pixel tests most of the time
https://bugs.webkit.org/show_bug.cgi?id=160016

Reviewed by Žan Doberšek.

WTR sends a force repaint message to the web process before taking a snapshot of the web view. With the threaded
compositor, the UI process is notified about the force repaint callback before the contents have been actually
painted. We need to ensure that the contents are rendered before the UI process is notified.

* Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
(WebKit::ThreadedCompositor::forceRepaint): Synchronously render the layer tree.
* Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewRenderAcceleratedCompositingResults): Always mark the redirected window surface as dirty before
rendering, since it can be modified by the web process at any time.
* UIProcess/gtk/RedirectedXCompositeWindow.cpp:
(WebKit::XDamageNotifier::add):
(WebKit::RedirectedXCompositeWindow::RedirectedXCompositeWindow): Do not mark the surface as dirty on every
damage since the view will do it before rendering.
* WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:
(WebKit::ThreadedCoordinatedLayerTreeHost::forceRepaint): Call ThreadedCompositor::forceRepaint().
* WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</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>
<li><a href="#trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp">trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessgtkRedirectedXCompositeWindowcpp">trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageCoordinatedGraphicsThreadedCoordinatedLayerTreeHostcpp">trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageCoordinatedGraphicsThreadedCoordinatedLayerTreeHosth">trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/ChangeLog        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -1,5 +1,30 @@
</span><span class="cx"> 2016-07-21  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><ins>+        [GTK][Threaded Compositor] WTR generates fully white images for pixel tests most of the time
+        https://bugs.webkit.org/show_bug.cgi?id=160016
+
+        Reviewed by Žan Doberšek.
+
+        WTR sends a force repaint message to the web process before taking a snapshot of the web view. With the threaded
+        compositor, the UI process is notified about the force repaint callback before the contents have been actually
+        painted. We need to ensure that the contents are rendered before the UI process is notified.
+
+        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
+        (WebKit::ThreadedCompositor::forceRepaint): Synchronously render the layer tree.
+        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewRenderAcceleratedCompositingResults): Always mark the redirected window surface as dirty before
+        rendering, since it can be modified by the web process at any time.
+        * UIProcess/gtk/RedirectedXCompositeWindow.cpp:
+        (WebKit::XDamageNotifier::add):
+        (WebKit::RedirectedXCompositeWindow::RedirectedXCompositeWindow): Do not mark the surface as dirty on every
+        damage since the view will do it before rendering.
+        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp:
+        (WebKit::ThreadedCoordinatedLayerTreeHost::forceRepaint): Call ThreadedCompositor::forceRepaint().
+        * WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h:
+
+2016-07-21  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
</ins><span class="cx">         [GTK] White page when loaded tab is visited until it's hovered when AC mode is always on
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=159512
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -185,6 +185,13 @@
</span><span class="cx">     m_compositingRunLoop-&gt;startUpdateTimer(CompositingRunLoop::Immediate);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ThreadedCompositor::forceRepaint()
+{
+    m_compositingRunLoop-&gt;performTaskSync([this, protectedThis = makeRef(*this)] {
+        renderLayerTree();
+    });
+}
+
</ins><span class="cx"> void ThreadedCompositor::didChangeVisibleRect()
</span><span class="cx"> {
</span><span class="cx">     RunLoop::main().dispatch([this, protectedThis = makeRef(*this), visibleRect = m_viewportController-&gt;visibleContentsRect(), scale = m_viewportController-&gt;pageScaleFactor()] {
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedCoordinatedGraphicsthreadedcompositorThreadedCompositorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.h        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -78,6 +78,8 @@
</span><span class="cx"> 
</span><span class="cx">     void invalidate();
</span><span class="cx"> 
</span><ins>+    void forceRepaint();
+
</ins><span class="cx"> private:
</span><span class="cx">     ThreadedCompositor(Client*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -609,6 +609,9 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        // The surface can be modified by the web process at any time, so we mark it
+        // as dirty to ensure we always render the updated contents as soon as possible.
+        cairo_surface_mark_dirty(surface);
</ins><span class="cx">         cairo_rectangle(cr, clipRect-&gt;x, clipRect-&gt;y, clipRect-&gt;width, clipRect-&gt;height);
</span><span class="cx">         cairo_set_source_surface(cr, surface, 0, 0);
</span><span class="cx">         cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessgtkRedirectedXCompositeWindowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void add(Window window, std::function&lt;void()&gt; notifyFunction)
</del><ins>+    void add(Window window, std::function&lt;void()&gt;&amp;&amp; notifyFunction)
</ins><span class="cx">     {
</span><span class="cx">         if (m_notifyFunctions.isEmpty())
</span><span class="cx">             gdk_window_add_filter(nullptr, reinterpret_cast&lt;GdkFilterFunc&gt;(&amp;filterXDamageEvent), this);
</span><span class="lines">@@ -189,12 +189,7 @@
</span><span class="cx">         &amp;windowAttributes);
</span><span class="cx">     XMapWindow(m_display, m_window.get());
</span><span class="cx"> 
</span><del>-    xDamageNotifier().add(m_window.get(), [this, damageNotify = WTFMove(damageNotify)] {
-        // The surface has been modified by the web process, mark it as dirty.
-        if (m_surface)
-            cairo_surface_mark_dirty(m_surface.get());
-        damageNotify();
-    });
</del><ins>+    xDamageNotifier().add(m_window.get(), WTFMove(damageNotify));
</ins><span class="cx"> 
</span><span class="cx">     while (1) {
</span><span class="cx">         XEvent event;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageCoordinatedGraphicsThreadedCoordinatedLayerTreeHostcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.cpp        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -60,6 +60,12 @@
</span><span class="cx">     CoordinatedLayerTreeHost::invalidate();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ThreadedCoordinatedLayerTreeHost::forceRepaint()
+{
+    CoordinatedLayerTreeHost::forceRepaint();
+    m_compositor-&gt;forceRepaint();
+}
+
</ins><span class="cx"> void ThreadedCoordinatedLayerTreeHost::scrollNonCompositedContents(const WebCore::IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     m_compositor-&gt;scrollTo(rect.location());
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageCoordinatedGraphicsThreadedCoordinatedLayerTreeHosth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h (203503 => 203504)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h        2016-07-21 16:01:20 UTC (rev 203503)
+++ trunk/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/ThreadedCoordinatedLayerTreeHost.h        2016-07-21 16:02:52 UTC (rev 203504)
</span><span class="lines">@@ -61,6 +61,9 @@
</span><span class="cx"> 
</span><span class="cx">     void invalidate() override;
</span><span class="cx"> 
</span><ins>+    void forceRepaint() override;
+    bool forceRepaintAsync(uint64_t callbackID) override { return false; }
+
</ins><span class="cx"> #if PLATFORM(GTK)
</span><span class="cx">     void setNativeSurfaceHandleForCompositing(uint64_t) override;
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>