<!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>[175153] 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/175153">175153</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-10-23 17:44:09 -0700 (Thu, 23 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS WK2] If a page has the exact same VisibleContentRect as the page before, its VisibleContentRectUpdate can be ignored
https://bugs.webkit.org/show_bug.cgi?id=138031
rdar://problem/18739335

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2014-10-23
Reviewed by Simon Fraser.

Since any VisibleContentRectUpdate is costly for the WebProcess, we avoid sending updates
if none of the important parameters have changed (scale and geometry).

One unintended side effect is that the update of a page can be blocked if the parameters
of the previous page were identical.

What happen is this:
1) Page [A] sends its content rect update as needed. WebPageProxy saves the last update
   in m_lastVisibleContentRectUpdate and use that value to avoid useless updates.
2) Page [B] load after page [A] and have the exact VisibleContentRect. When receiving the first
   layer tree commit after didCommitLoadForFrame, WKWebView sends its VisibleContentRect
   to WebPageProxy to synchronize the state of the WebProcess with what is on screen.
3) Since the two VisibleContentRect update has the same value as the ones of page [A], WebPageProxy
   discards the update. The WebProcess has its initialization viewport and is not udpated until
   a major parameter changes (scale or position).

In rdar://problem/18739335, the problem is the similar but with a different failure point:
1) Everything above happened already.
2) The layer tree transaction has a scrolling request. This is processed by WKWebView.
3) Since the scrolling position is invalid, the request is ignored and we send the last
   VisibleContentRect to the WebProcess with WebPageProxy::resendLastVisibleContentRects().
4) Since the VisibleContentRect was never updated after didCommitLoadForFrame, the one we send
   is for the previous page, which the web process correctly ignores.

This patch solves the problem by nuking the cached m_lastVisibleContentRectUpdate before
any valid VisibleContentRectUpdate for a new page.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
(WebKit::WebPageProxy::didCommitLoadForFrame):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::didCommitLayerTree):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxycpp">trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (175152 => 175153)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-10-23 23:49:05 UTC (rev 175152)
+++ trunk/Source/WebKit2/ChangeLog        2014-10-24 00:44:09 UTC (rev 175153)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2014-10-23  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [iOS WK2] If a page has the exact same VisibleContentRect as the page before, its VisibleContentRectUpdate can be ignored
+        https://bugs.webkit.org/show_bug.cgi?id=138031
+        rdar://problem/18739335
+
+        Reviewed by Simon Fraser.
+
+        Since any VisibleContentRectUpdate is costly for the WebProcess, we avoid sending updates
+        if none of the important parameters have changed (scale and geometry).
+
+        One unintended side effect is that the update of a page can be blocked if the parameters
+        of the previous page were identical.
+
+        What happen is this:
+        1) Page [A] sends its content rect update as needed. WebPageProxy saves the last update
+           in m_lastVisibleContentRectUpdate and use that value to avoid useless updates.
+        2) Page [B] load after page [A] and have the exact VisibleContentRect. When receiving the first
+           layer tree commit after didCommitLoadForFrame, WKWebView sends its VisibleContentRect
+           to WebPageProxy to synchronize the state of the WebProcess with what is on screen.
+        3) Since the two VisibleContentRect update has the same value as the ones of page [A], WebPageProxy
+           discards the update. The WebProcess has its initialization viewport and is not udpated until
+           a major parameter changes (scale or position).
+
+        In rdar://problem/18739335, the problem is the similar but with a different failure point:
+        1) Everything above happened already.
+        2) The layer tree transaction has a scrolling request. This is processed by WKWebView.
+        3) Since the scrolling position is invalid, the request is ignored and we send the last
+           VisibleContentRect to the WebProcess with WebPageProxy::resendLastVisibleContentRects().
+        4) Since the VisibleContentRect was never updated after didCommitLoadForFrame, the one we send
+           is for the previous page, which the web process correctly ignores.
+
+        This patch solves the problem by nuking the cached m_lastVisibleContentRectUpdate before
+        any valid VisibleContentRectUpdate for a new page.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        (WebKit::WebPageProxy::didCommitLoadForFrame):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::didCommitLayerTree):
+
</ins><span class="cx"> 2014-10-23  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Provide a way to have alternate inspector agents
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (175152 => 175153)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-10-23 23:49:05 UTC (rev 175152)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp        2014-10-24 00:44:09 UTC (rev 175153)
</span><span class="lines">@@ -131,6 +131,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><ins>+#include &quot;RemoteLayerTreeDrawingAreaProxy.h&quot;
</ins><span class="cx"> #include &quot;WebVideoFullscreenManagerProxy.h&quot;
</span><span class="cx"> #include &quot;WebVideoFullscreenManagerProxyMessages.h&quot;
</span><span class="cx"> #endif
</span><span class="lines">@@ -269,6 +270,8 @@
</span><span class="cx">     , m_mainFrame(nullptr)
</span><span class="cx">     , m_userAgent(standardUserAgent())
</span><span class="cx"> #if PLATFORM(IOS)
</span><ins>+    , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
+    , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(0)
</ins><span class="cx">     , m_deviceOrientation(0)
</span><span class="cx">     , m_dynamicViewportSizeUpdateWaitingForTarget(false)
</span><span class="cx">     , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
</span><span class="lines">@@ -2615,6 +2618,13 @@
</span><span class="cx">     WebFrameProxy* frame = m_process-&gt;webFrame(frameID);
</span><span class="cx">     MESSAGE_CHECK(frame);
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    if (frame-&gt;isMainFrame()) {
+        m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
+        m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = downcast&lt;RemoteLayerTreeDrawingAreaProxy&gt;(*drawingArea()).nextLayerTreeTransactionID();
+    }
+#endif
+
</ins><span class="cx">     auto transaction = m_pageLoadState.transaction();
</span><span class="cx"> 
</span><span class="cx">     if (frame-&gt;isMainFrame())
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (175152 => 175153)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-10-23 23:49:05 UTC (rev 175152)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-10-24 00:44:09 UTC (rev 175153)
</span><span class="lines">@@ -1357,6 +1357,8 @@
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     RefPtr&lt;WebVideoFullscreenManagerProxy&gt; m_videoFullscreenManager;
</span><span class="cx">     VisibleContentRectUpdateInfo m_lastVisibleContentRectUpdate;
</span><ins>+    bool m_hasReceivedLayerTreeTransactionAfterDidCommitLoad;
+    uint64_t m_firstLayerTreeTransactionIdAfterDidCommitLoad;
</ins><span class="cx">     int32_t m_deviceOrientation;
</span><span class="cx">     bool m_dynamicViewportSizeUpdateWaitingForTarget;
</span><span class="cx">     bool m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (175152 => 175153)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-10-23 23:49:05 UTC (rev 175152)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-10-24 00:44:09 UTC (rev 175153)
</span><span class="lines">@@ -336,6 +336,13 @@
</span><span class="cx"> {
</span><span class="cx">     m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
</span><span class="cx"> 
</span><ins>+    if (!m_hasReceivedLayerTreeTransactionAfterDidCommitLoad) {
+        if (layerTreeTransaction.transactionID() &gt;= m_firstLayerTreeTransactionIdAfterDidCommitLoad) {
+            m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = true;
+            m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo();
+        }
+    }
+
</ins><span class="cx">     if (!m_dynamicViewportSizeUpdateWaitingForTarget &amp;&amp; m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit) {
</span><span class="cx">         if (layerTreeTransaction.transactionID() &gt;= m_dynamicViewportSizeUpdateLayerTreeTransactionID)
</span><span class="cx">             m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
</span></span></pre>
</div>
</div>

</body>
</html>