Title: [175153] trunk/Source/WebKit2
Revision
175153
Author
benja...@webkit.org
Date
2014-10-23 17:44:09 -0700 (Thu, 23 Oct 2014)

Log Message

[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 <bpoul...@apple.com> 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):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (175152 => 175153)


--- 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)
@@ -1,3 +1,45 @@
+2014-10-23  Benjamin Poulain  <bpoul...@apple.com>
+
+        [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):
+
 2014-10-23  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: Provide a way to have alternate inspector agents

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (175152 => 175153)


--- 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)
@@ -131,6 +131,7 @@
 #endif
 
 #if PLATFORM(IOS)
+#include "RemoteLayerTreeDrawingAreaProxy.h"
 #include "WebVideoFullscreenManagerProxy.h"
 #include "WebVideoFullscreenManagerProxyMessages.h"
 #endif
@@ -269,6 +270,8 @@
     , m_mainFrame(nullptr)
     , m_userAgent(standardUserAgent())
 #if PLATFORM(IOS)
+    , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(true)
+    , m_hasReceivedLayerTreeTransactionAfterDidCommitLoad(0)
     , m_deviceOrientation(0)
     , m_dynamicViewportSizeUpdateWaitingForTarget(false)
     , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
@@ -2615,6 +2618,13 @@
     WebFrameProxy* frame = m_process->webFrame(frameID);
     MESSAGE_CHECK(frame);
 
+#if PLATFORM(IOS)
+    if (frame->isMainFrame()) {
+        m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false;
+        m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID();
+    }
+#endif
+
     auto transaction = m_pageLoadState.transaction();
 
     if (frame->isMainFrame())

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (175152 => 175153)


--- 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)
@@ -1357,6 +1357,8 @@
 #if PLATFORM(IOS)
     RefPtr<WebVideoFullscreenManagerProxy> m_videoFullscreenManager;
     VisibleContentRectUpdateInfo m_lastVisibleContentRectUpdate;
+    bool m_hasReceivedLayerTreeTransactionAfterDidCommitLoad;
+    uint64_t m_firstLayerTreeTransactionIdAfterDidCommitLoad;
     int32_t m_deviceOrientation;
     bool m_dynamicViewportSizeUpdateWaitingForTarget;
     bool m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit;

Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (175152 => 175153)


--- 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)
@@ -336,6 +336,13 @@
 {
     m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
 
+    if (!m_hasReceivedLayerTreeTransactionAfterDidCommitLoad) {
+        if (layerTreeTransaction.transactionID() >= m_firstLayerTreeTransactionIdAfterDidCommitLoad) {
+            m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = true;
+            m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo();
+        }
+    }
+
     if (!m_dynamicViewportSizeUpdateWaitingForTarget && m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit) {
         if (layerTreeTransaction.transactionID() >= m_dynamicViewportSizeUpdateLayerTreeTransactionID)
             m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to