<!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>[202273] 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/202273">202273</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-06-21 04:04:53 -0700 (Tue, 21 Jun 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GTK] Web view is not redrawn when reparented in force compositing mode
https://bugs.webkit.org/show_bug.cgi?id=158689

Reviewed by Žan Doberšek.

When the web view is reparented in accelerated compositing mode, the UI process always exits the accelerated
mode when the view is unrealized, because the native surface handle for compositing is destroyed, but it doesn't
enter again when the view is realized and a new native surface handle for compositing is used. This happens
because the UI and Web processes are not in sync regarding whether the page is in accelerated compositing or
not. The Web process never exits accelerated mode when compositing mode is forced, but the UI process doesn't
check that setting at all.

* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseResizeRedirectedWindow): Helper function to ensure the redirected window size is properly updated.
(webkitWebViewBaseRealize): Resize the redirected window if the view is already in AC mode when realized.
(webkitWebViewRenderAcceleratedCompositingResults): Use webkitWebViewBaseResizeRedirectedWindow().
(webkitWebViewBaseSizeAllocate): Ditto.
(webkitWebViewBaseWillEnterAcceleratedCompositingMode): Ditto.
* UIProcess/DrawingAreaProxyImpl.cpp:
(WebKit::DrawingAreaProxyImpl::alwaysUseCompositing): Return true in force compositing mode.
(WebKit::DrawingAreaProxyImpl::enterAcceleratedCompositingMode): Update assert.
(WebKit::DrawingAreaProxyImpl::exitAcceleratedCompositingMode): Do not exit AC mode compositing mode is always enabled.
* UIProcess/DrawingAreaProxyImpl.h:
(WebKit::DrawingAreaProxyImpl::isInAcceleratedCompositingMode): Return true also in force compositing mode.
* UIProcess/gtk/RedirectedXCompositeWindow.cpp:
(WebKit::RedirectedXCompositeWindow::surface): Ensure we never return an uninitialized surface to prevent
rendering artifacts in in force compositing mode when waiting for the first update on the redirected window.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp">trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessDrawingAreaProxyImplcpp">trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessDrawingAreaProxyImplh">trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessgtkRedirectedXCompositeWindowcpp">trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (202272 => 202273)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-06-21 08:32:06 UTC (rev 202272)
+++ trunk/Source/WebKit2/ChangeLog        2016-06-21 11:04:53 UTC (rev 202273)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2016-06-21  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] Web view is not redrawn when reparented in force compositing mode
+        https://bugs.webkit.org/show_bug.cgi?id=158689
+
+        Reviewed by Žan Doberšek.
+
+        When the web view is reparented in accelerated compositing mode, the UI process always exits the accelerated
+        mode when the view is unrealized, because the native surface handle for compositing is destroyed, but it doesn't
+        enter again when the view is realized and a new native surface handle for compositing is used. This happens
+        because the UI and Web processes are not in sync regarding whether the page is in accelerated compositing or
+        not. The Web process never exits accelerated mode when compositing mode is forced, but the UI process doesn't
+        check that setting at all.
+
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseResizeRedirectedWindow): Helper function to ensure the redirected window size is properly updated.
+        (webkitWebViewBaseRealize): Resize the redirected window if the view is already in AC mode when realized.
+        (webkitWebViewRenderAcceleratedCompositingResults): Use webkitWebViewBaseResizeRedirectedWindow().
+        (webkitWebViewBaseSizeAllocate): Ditto.
+        (webkitWebViewBaseWillEnterAcceleratedCompositingMode): Ditto.
+        * UIProcess/DrawingAreaProxyImpl.cpp:
+        (WebKit::DrawingAreaProxyImpl::alwaysUseCompositing): Return true in force compositing mode.
+        (WebKit::DrawingAreaProxyImpl::enterAcceleratedCompositingMode): Update assert.
+        (WebKit::DrawingAreaProxyImpl::exitAcceleratedCompositingMode): Do not exit AC mode compositing mode is always enabled.
+        * UIProcess/DrawingAreaProxyImpl.h:
+        (WebKit::DrawingAreaProxyImpl::isInAcceleratedCompositingMode): Return true also in force compositing mode.
+        * UIProcess/gtk/RedirectedXCompositeWindow.cpp:
+        (WebKit::RedirectedXCompositeWindow::surface): Ensure we never return an uninitialized surface to prevent
+        rendering artifacts in in force compositing mode when waiting for the first update on the redirected window.
+
</ins><span class="cx"> 2016-06-20  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r202243.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIgtkWebKitWebViewBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (202272 => 202273)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-06-21 08:32:06 UTC (rev 202272)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp        2016-06-21 11:04:53 UTC (rev 202273)
</span><span class="lines">@@ -354,6 +354,17 @@
</span><span class="cx">         priv-&gt;toplevelWindowRealizedID = g_signal_connect_swapped(window, &quot;realize&quot;, G_CALLBACK(toplevelWindowRealized), webViewBase);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if USE(REDIRECTED_XCOMPOSITE_WINDOW)
+static void webkitWebViewBaseResizeRedirectedWindow(WebKitWebViewBase* webView)
+{
+    WebKitWebViewBasePrivate* priv = webView-&gt;priv;
+    DrawingAreaProxyImpl* drawingArea = static_cast&lt;DrawingAreaProxyImpl*&gt;(priv-&gt;pageProxy-&gt;drawingArea());
+    ASSERT(drawingArea);
+    priv-&gt;redirectedWindow-&gt;setDeviceScaleFactor(priv-&gt;pageProxy-&gt;deviceScaleFactor());
+    priv-&gt;redirectedWindow-&gt;resize(drawingArea-&gt;size());
+}
+#endif
+
</ins><span class="cx"> static void webkitWebViewBaseRealize(GtkWidget* widget)
</span><span class="cx"> {
</span><span class="cx">     WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget);
</span><span class="lines">@@ -370,8 +381,11 @@
</span><span class="cx">                     gtk_widget_queue_draw(GTK_WIDGET(webView));
</span><span class="cx">             });
</span><span class="cx">         if (priv-&gt;redirectedWindow) {
</span><del>-            if (DrawingAreaProxyImpl* drawingArea = static_cast&lt;DrawingAreaProxyImpl*&gt;(priv-&gt;pageProxy-&gt;drawingArea()))
</del><ins>+            if (DrawingAreaProxyImpl* drawingArea = static_cast&lt;DrawingAreaProxyImpl*&gt;(priv-&gt;pageProxy-&gt;drawingArea())) {
</ins><span class="cx">                 drawingArea-&gt;setNativeSurfaceHandleForCompositing(priv-&gt;redirectedWindow-&gt;windowID());
</span><ins>+                if (drawingArea-&gt;isInAcceleratedCompositingMode())
+                    webkitWebViewBaseResizeRedirectedWindow(webView);
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="lines">@@ -575,9 +589,7 @@
</span><span class="cx">     if (!priv-&gt;redirectedWindow)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    priv-&gt;redirectedWindow-&gt;setDeviceScaleFactor(webViewBase-&gt;priv-&gt;pageProxy-&gt;deviceScaleFactor());
-    priv-&gt;redirectedWindow-&gt;resize(drawingArea-&gt;size());
-
</del><ins>+    webkitWebViewBaseResizeRedirectedWindow(webViewBase);
</ins><span class="cx">     if (cairo_surface_t* surface = priv-&gt;redirectedWindow-&gt;surface()) {
</span><span class="cx">         cairo_save(cr);
</span><span class="cx">         cairo_rectangle(cr, clipRect-&gt;x, clipRect-&gt;y, clipRect-&gt;width, clipRect-&gt;height);
</span><span class="lines">@@ -691,7 +703,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(REDIRECTED_XCOMPOSITE_WINDOW)
</span><span class="cx">     if (priv-&gt;redirectedWindow &amp;&amp; drawingArea-&gt;isInAcceleratedCompositingMode())
</span><del>-        priv-&gt;redirectedWindow-&gt;resize(viewRect.size());
</del><ins>+        webkitWebViewBaseResizeRedirectedWindow(webViewBase);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     drawingArea-&gt;setSize(viewRect.size(), IntSize(), IntSize());
</span><span class="lines">@@ -1557,8 +1569,7 @@
</span><span class="cx">     if (!drawingArea)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    priv-&gt;redirectedWindow-&gt;setDeviceScaleFactor(webkitWebViewBase-&gt;priv-&gt;pageProxy-&gt;deviceScaleFactor());
-    priv-&gt;redirectedWindow-&gt;resize(drawingArea-&gt;size());
</del><ins>+    webkitWebViewBaseResizeRedirectedWindow(webkitWebViewBase);
</ins><span class="cx"> 
</span><span class="cx">     // Clear the redirected window if we don't enter AC mode in the end.
</span><span class="cx">     webkitWebViewBaseClearRedirectedWindowSoon(webkitWebViewBase);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessDrawingAreaProxyImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp (202272 => 202273)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp        2016-06-21 08:32:06 UTC (rev 202272)
+++ trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp        2016-06-21 11:04:53 UTC (rev 202273)
</span><span class="lines">@@ -58,6 +58,11 @@
</span><span class="cx">         exitAcceleratedCompositingMode();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool DrawingAreaProxyImpl::alwaysUseCompositing() const
+{
+    return m_webPageProxy.preferences().acceleratedCompositingEnabled() &amp;&amp; m_webPageProxy.preferences().forceCompositingMode();
+}
+
</ins><span class="cx"> void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, const IntRect&amp; rect, Region&amp; unpaintedRegion)
</span><span class="cx"> {
</span><span class="cx">     unpaintedRegion = rect;
</span><span class="lines">@@ -295,7 +300,7 @@
</span><span class="cx"> 
</span><span class="cx"> void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext&amp; layerTreeContext)
</span><span class="cx"> {
</span><del>-    ASSERT(!isInAcceleratedCompositingMode());
</del><ins>+    ASSERT(alwaysUseCompositing() || !isInAcceleratedCompositingMode());
</ins><span class="cx"> 
</span><span class="cx">     m_backingStore = nullptr;
</span><span class="cx">     m_layerTreeContext = layerTreeContext;
</span><span class="lines">@@ -329,8 +334,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isInAcceleratedCompositingMode());
</span><span class="cx"> 
</span><del>-    m_layerTreeContext = LayerTreeContext();    
-    m_webPageProxy.exitAcceleratedCompositingMode();
</del><ins>+    m_layerTreeContext = LayerTreeContext();
+    if (!alwaysUseCompositing())
+        m_webPageProxy.exitAcceleratedCompositingMode();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DrawingAreaProxyImpl::updateAcceleratedCompositingMode(const LayerTreeContext&amp; layerTreeContext)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessDrawingAreaProxyImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h (202272 => 202273)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h        2016-06-21 08:32:06 UTC (rev 202272)
+++ trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h        2016-06-21 11:04:53 UTC (rev 202273)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx"> 
</span><span class="cx">     void paint(BackingStore::PlatformGraphicsContext, const WebCore::IntRect&amp;, WebCore::Region&amp; unpaintedRegion);
</span><span class="cx"> 
</span><del>-    bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); }
</del><ins>+    bool isInAcceleratedCompositingMode() const { return alwaysUseCompositing() || !m_layerTreeContext.isEmpty(); }
</ins><span class="cx"> 
</span><span class="cx">     bool hasReceivedFirstUpdate() const { return m_hasReceivedFirstUpdate; }
</span><span class="cx"> 
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx">     void enterAcceleratedCompositingMode(const LayerTreeContext&amp;);
</span><span class="cx">     void exitAcceleratedCompositingMode();
</span><span class="cx">     void updateAcceleratedCompositingMode(const LayerTreeContext&amp;);
</span><ins>+    bool alwaysUseCompositing() const;
</ins><span class="cx"> 
</span><span class="cx">     void discardBackingStoreSoon();
</span><span class="cx">     void discardBackingStore();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessgtkRedirectedXCompositeWindowcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp (202272 => 202273)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp        2016-06-21 08:32:06 UTC (rev 202272)
+++ trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp        2016-06-21 11:04:53 UTC (rev 202273)
</span><span class="lines">@@ -263,14 +263,15 @@
</span><span class="cx">     RefPtr&lt;cairo_surface_t&gt; newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap.get(), windowAttributes.visual, m_size.width(), m_size.height()));
</span><span class="cx">     cairoSurfaceSetDeviceScale(newSurface.get(), m_deviceScale, m_deviceScale);
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;cairo_t&gt; cr = adoptRef(cairo_create(newSurface.get()));
+    cairo_set_source_rgb(cr.get(), 1, 1, 1);
+    cairo_paint(cr.get());
+
</ins><span class="cx">     // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
</span><span class="cx">     // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
</span><span class="cx">     // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
</span><span class="cx">     // pixmap to the new one to properly initialize it.
</span><span class="cx">     if (m_surface) {
</span><del>-        RefPtr&lt;cairo_t&gt; cr = adoptRef(cairo_create(newSurface.get()));
-        cairo_set_source_rgb(cr.get(), 1, 1, 1);
-        cairo_paint(cr.get());
</del><span class="cx">         cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
</span><span class="cx">         cairo_paint(cr.get());
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>