<!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>[208662] trunk</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/208662">208662</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-11-12 19:24:27 -0800 (Sat, 12 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS WK2] Share some code with Mac for post-async-scroll state reconciliation
https://bugs.webkit.org/show_bug.cgi?id=164694

Reviewed by Zalan Bujtas.

Source/WebCore:

When an async scroll notifications get back to the main thread in
AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(), we call
syncViewportConstrainedLayerPositions() to poke the new layer positions on the
GraphicsLayers to match the changes made on the scrolling thread.

However, this was not done on iOS, which will be problematic for a future patch
where we require GraphicsLayer positions and the current fixedPositionViewport rect
to have been computed when in a consistent state.

Fix by factoring some code into reconcileScrollingState(), which is called on iOS/WK2
from WebPage::updateVisibleContentRects() rather than setting the FrameView's scroll offset
directly.

Test: scrollingcoordinator/ios/sync-layer-positions-after-scroll.html

* page/WheelEventDeltaFilter.cpp:
(WebCore::WheelEventDeltaFilter::filteredDelta):
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
(WebCore::AsyncScrollingCoordinator::reconcileScrollingState):
(WebCore::AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions):
(WebCore::AsyncScrollingCoordinator::syncChildPositions): Deleted.
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::reconcileScrollingState):
(WebCore::ScrollingCoordinator::syncViewportConstrainedLayerPositions):
(WebCore::ScrollingCoordinator::syncChildPositions): Deleted.
* page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
(WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition):
* platform/Logging.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::setScrollOffset):
* platform/graphics/ca/TileController.cpp:
(WebCore::TileController::adjustTileCoverageRect):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::updateLayerPositionsAfterDocumentScroll):

Source/WebKit2:

Rather than calling FrameView directly, call reconcileScrollingState() on the scrolling
coordinator.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::updateVisibleContentRects):

LayoutTests:

Test that pans the page, and dumps GraphicsLayers before letting go.

* TestExpectations:
* platform/ios-simulator-wk2/TestExpectations:
* scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt: Added.
* scrollingcoordinator/ios/sync-layer-positions-after-scroll.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorwk2TestExpectations">trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageWheelEventDeltaFiltercpp">trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp">trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorh">trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingCoordinatorh">trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingTreeFrameScrollingNodecpp">trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformLoggingh">trunk/Source/WebCore/platform/Logging.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollViewcpp">trunk/Source/WebCore/platform/ScrollView.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaTileControllercpp">trunk/Source/WebCore/platform/graphics/ca/TileController.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/LayoutTests/scrollingcoordinator/ios/</li>
<li><a href="#trunkLayoutTestsscrollingcoordinatoriossynclayerpositionsafterscrollexpectedtxt">trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt</a></li>
<li><a href="#trunkLayoutTestsscrollingcoordinatoriossynclayerpositionsafterscrollhtml">trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/LayoutTests/ChangeLog        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-11-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        [iOS WK2] Share some code with Mac for post-async-scroll state reconciliation
+        https://bugs.webkit.org/show_bug.cgi?id=164694
+
+        Reviewed by Zalan Bujtas.
+
+        Test that pans the page, and dumps GraphicsLayers before letting go.
+
+        * TestExpectations:
+        * platform/ios-simulator-wk2/TestExpectations:
+        * scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt: Added.
+        * scrollingcoordinator/ios/sync-layer-positions-after-scroll.html: Added.
+
</ins><span class="cx"> 2016-11-12  Frederic Wang  &lt;fwang@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Ensure MathML render tree are clean by the end of FrameView::layout().
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/LayoutTests/TestExpectations        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> fast/events/ios [ Skip ]
</span><span class="cx"> fast/events/touch/ios [ Skip ]
</span><span class="cx"> fast/scrolling/ios [ Skip ]
</span><ins>+scrollingcoordinator/ios [ Skip ]
</ins><span class="cx"> fast/content-observation [ Skip ]
</span><span class="cx"> media/mac [ Skip ]
</span><span class="cx"> media/controls/ipad [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorwk2TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -8,6 +8,7 @@
</span><span class="cx"> 
</span><span class="cx"> fast/scrolling/ios [ Pass ]
</span><span class="cx"> fast/viewport/ios [ Pass ]
</span><ins>+scrollingcoordinator/ios [ Pass ]
</ins><span class="cx"> editing/selection/character-granularity-rect.html [ Pass ]
</span><span class="cx"> 
</span><span class="cx"> #//////////////////////////////////////////////////////////////////////////////////////////
</span></span></pre></div>
<a id="trunkLayoutTestsscrollingcoordinatoriossynclayerpositionsafterscrollexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt (0 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt                                (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll-expected.txt        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+visibleRectAfterScroll: {&quot;left&quot;:0,&quot;top&quot;:156.5,&quot;width&quot;:800,&quot;height&quot;:600}
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 1308.00 2021.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 1308.00 2021.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 12.00 10.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+      )
+    )
+  )
+)
+
</ins></span></pre></div>
<a id="trunkLayoutTestsscrollingcoordinatoriossynclayerpositionsafterscrollhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll.html (0 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll.html                                (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/ios/sync-layer-positions-after-scroll.html        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -0,0 +1,120 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        body {
+            width: 1300px;
+            height: 2000px;
+        }
+        
+        .fixed {
+            position: fixed;
+            top: 10px;
+            left: 12px;
+            height: 100px;
+            width: 100px;
+            background-color: blue;
+        }
+    &lt;/style&gt;
+    &lt;script&gt;
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        function getDragUIScript(startX, startY, endX, endY)
+        {
+            return `(function() {
+                var movedFingerDownStream = {
+                    events : [
+                        {
+                            inputType : &quot;hand&quot;,
+                            timeOffset : 0,
+                            touches : [
+                                {
+                                    inputType : &quot;finger&quot;,
+                                    phase : &quot;began&quot;,
+                                    id : 1,
+                                    x : ${startX},
+                                    y : ${startY}
+                                }
+                            ]
+                        },
+                        {
+                            interpolate : &quot;linear&quot;,
+                            timestep: 0.025,
+                            startEvent : {
+                                inputType : &quot;hand&quot;,
+                                timeOffset : 0,
+                                touches : [
+                                    {
+                                        inputType : &quot;finger&quot;,
+                                        phase : &quot;moved&quot;,
+                                        id : 1,
+                                        x : ${startX},
+                                        y : ${startY}
+                                    }
+                                ]
+                            },
+                            endEvent : {
+                                inputType : &quot;hand&quot;,
+                                timeOffset : 0.15,
+                                touches : [
+                                    {
+                                        inputType : &quot;finger&quot;,
+                                        phase : &quot;moved&quot;,
+                                        id : 1,
+                                        x : ${endX},
+                                        y : ${endY}
+                                    }
+                                ]
+                            }
+                        }
+                    ]
+                };
+
+                uiController.sendEventStream(JSON.stringify(movedFingerDownStream), function() {
+                    uiController.uiScriptComplete(JSON.stringify(uiController.contentVisibleRect));
+                });
+            })();`;
+        }
+
+        function getFingerUpUIScript(x, y)
+        {
+            return `(function() {
+                uiController.liftUpAtPoint(${x}, ${y}, 1, function() {
+                    uiController.uiScriptComplete('');
+                });
+            })();`;
+        }
+
+        function doTest()
+        {
+            if (!testRunner.runUIScript)
+                return
+
+            window.setTimeout(function() {
+                var xPos = 100;
+                var startY = 300;
+                var endY = 100;
+                // Send touch down and moves (keep the finger down).
+                testRunner.runUIScript(getDragUIScript(xPos, startY, xPos, endY), function(visibleRectAfterScroll) {
+                    var result = 'visibleRectAfterScroll: ' + visibleRectAfterScroll + '\n' + internals.layerTreeAsText(document);
+                    document.getElementById('layers').textContent = result;
+                    // Now send the finel touch up.
+                    testRunner.runUIScript(getFingerUpUIScript(xPos, endY), function() {
+                        testRunner.notifyDone();
+                    });
+                });
+            }, 0);
+        }
+        
+        window.addEventListener('load', doTest, false);
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div class=&quot;fixed&quot;&gt;&lt;/div&gt;
+&lt;pre id=&quot;layers&quot;&gt;&lt;/pre&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/ChangeLog        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-11-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        [iOS WK2] Share some code with Mac for post-async-scroll state reconciliation
+        https://bugs.webkit.org/show_bug.cgi?id=164694
+
+        Reviewed by Zalan Bujtas.
+
+        When an async scroll notifications get back to the main thread in
+        AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(), we call 
+        syncViewportConstrainedLayerPositions() to poke the new layer positions on the
+        GraphicsLayers to match the changes made on the scrolling thread.
+
+        However, this was not done on iOS, which will be problematic for a future patch
+        where we require GraphicsLayer positions and the current fixedPositionViewport rect
+        to have been computed when in a consistent state.
+
+        Fix by factoring some code into reconcileScrollingState(), which is called on iOS/WK2
+        from WebPage::updateVisibleContentRects() rather than setting the FrameView's scroll offset
+        directly.
+
+        Test: scrollingcoordinator/ios/sync-layer-positions-after-scroll.html
+
+        * page/WheelEventDeltaFilter.cpp:
+        (WebCore::WheelEventDeltaFilter::filteredDelta):
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
+        (WebCore::AsyncScrollingCoordinator::reconcileScrollingState):
+        (WebCore::AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions):
+        (WebCore::AsyncScrollingCoordinator::syncChildPositions): Deleted.
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::reconcileScrollingState):
+        (WebCore::ScrollingCoordinator::syncViewportConstrainedLayerPositions):
+        (WebCore::ScrollingCoordinator::syncChildPositions): Deleted.
+        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
+        (WebCore::ScrollingTreeFrameScrollingNode::layoutViewportForScrollPosition):
+        * platform/Logging.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::setScrollOffset):
+        * platform/graphics/ca/TileController.cpp:
+        (WebCore::TileController::adjustTileCoverageRect):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::updateLayerPositionsAfterDocumentScroll):
+
</ins><span class="cx"> 2016-11-12  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         RenderObject::flowThreadState should follow containing block instead of parent.
</span></span></pre></div>
<a id="trunkSourceWebCorepageWheelEventDeltaFiltercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/page/WheelEventDeltaFilter.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -60,7 +60,6 @@
</span><span class="cx"> 
</span><span class="cx"> FloatSize WheelEventDeltaFilter::filteredDelta() const
</span><span class="cx"> {
</span><del>-    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;BasicWheelEventDeltaFilter::filteredDelta returning &quot; &lt;&lt; m_currentFilteredDelta);
</del><span class="cx">     return m_currentFilteredDelta;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> #include &quot;ScrollingStateStickyNode.h&quot;
</span><span class="cx"> #include &quot;ScrollingStateTree.h&quot;
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><ins>+#include &quot;TextStream.h&quot;
</ins><span class="cx"> #include &quot;WheelEventTestTrigger.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -307,75 +308,13 @@
</span><span class="cx">     if (!frameViewPtr)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll node &quot; &lt;&lt; scrollingNodeID &lt;&lt; &quot; scrollPosition &quot; &lt;&lt; scrollPosition &lt;&lt; (scrollingLayerPositionAction == SetScrollingLayerPosition ? &quot; set&quot; : &quot; sync&quot;) &lt;&lt; &quot; layer positions&quot;);
+
</ins><span class="cx">     FrameView&amp; frameView = *frameViewPtr;
</span><span class="cx"> 
</span><span class="cx">     if (scrollingNodeID == frameView.scrollLayerID()) {
</span><del>-        bool oldProgrammaticScroll = frameView.inProgrammaticScroll();
-        frameView.setInProgrammaticScroll(programmaticScroll);
</del><ins>+        reconcileScrollingState(frameView, scrollPosition, layoutViewportOrigin, programmaticScroll, scrollingLayerPositionAction);
</ins><span class="cx"> 
</span><del>-        if (layoutViewportOrigin)
-            frameView.setLayoutViewportOrigin(LayoutPoint(layoutViewportOrigin.value()), FrameView::TriggerLayoutOrNot::No);
-
-        frameView.setConstrainsScrollingToContentEdge(false);
-        frameView.notifyScrollPositionChanged(roundedIntPoint(scrollPosition));
-        frameView.setConstrainsScrollingToContentEdge(true);
-        frameView.setInProgrammaticScroll(oldProgrammaticScroll);
-
-        if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) {
-            GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView);
-            GraphicsLayer* insetClipLayer = insetClipLayerForFrameView(frameView);
-            GraphicsLayer* contentShadowLayer = contentShadowLayerForFrameView(frameView);
-            GraphicsLayer* scrolledContentsLayer = rootContentLayerForFrameView(frameView);
-            GraphicsLayer* headerLayer = headerLayerForFrameView(frameView);
-            GraphicsLayer* footerLayer = footerLayerForFrameView(frameView);
-
-            ASSERT(frameView.scrollPosition() == roundedIntPoint(scrollPosition));
-            LayoutPoint scrollPositionForFixed = visualViewportEnabled() ? frameView.layoutViewportOrigin() : frameView.scrollPositionForFixedPosition();
-            float topContentInset = frameView.topContentInset();
-
-            FloatPoint positionForInsetClipLayer;
-            if (insetClipLayer)
-                positionForInsetClipLayer = FloatPoint(insetClipLayer-&gt;position().x(), FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
-            FloatPoint positionForContentsLayer = frameView.positionForRootContentLayer();
-            
-            FloatPoint positionForHeaderLayer = FloatPoint(scrollPositionForFixed.x(), FrameView::yPositionForHeaderLayer(scrollPosition, topContentInset));
-            FloatPoint positionForFooterLayer = FloatPoint(scrollPositionForFixed.x(),
-                FrameView::yPositionForFooterLayer(scrollPosition, topContentInset, frameView.totalContentsSize().height(), frameView.footerHeight()));
-
-            if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) {
-                scrollLayer-&gt;setPosition(-frameView.scrollPosition());
-                if (counterScrollingLayer)
-                    counterScrollingLayer-&gt;setPosition(scrollPositionForFixed);
-                if (insetClipLayer)
-                    insetClipLayer-&gt;setPosition(positionForInsetClipLayer);
-                if (contentShadowLayer)
-                    contentShadowLayer-&gt;setPosition(positionForContentsLayer);
-                if (scrolledContentsLayer)
-                    scrolledContentsLayer-&gt;setPosition(positionForContentsLayer);
-                if (headerLayer)
-                    headerLayer-&gt;setPosition(positionForHeaderLayer);
-                if (footerLayer)
-                    footerLayer-&gt;setPosition(positionForFooterLayer);
-            } else {
-                scrollLayer-&gt;syncPosition(-frameView.scrollPosition());
-                if (counterScrollingLayer)
-                    counterScrollingLayer-&gt;syncPosition(scrollPositionForFixed);
-                if (insetClipLayer)
-                    insetClipLayer-&gt;syncPosition(positionForInsetClipLayer);
-                if (contentShadowLayer)
-                    contentShadowLayer-&gt;syncPosition(positionForContentsLayer);
-                if (scrolledContentsLayer)
-                    scrolledContentsLayer-&gt;syncPosition(positionForContentsLayer);
-                if (headerLayer)
-                    headerLayer-&gt;syncPosition(positionForHeaderLayer);
-                if (footerLayer)
-                    footerLayer-&gt;syncPosition(positionForFooterLayer);
-
-                LayoutRect viewportRect = frameView.rectForFixedPositionLayout();
-                syncChildPositions(viewportRect);
-            }
-        }
-
</del><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">         if (m_page-&gt;expectsWheelEventTriggers()) {
</span><span class="cx">             frameView.scrollAnimator().setWheelEventTestTrigger(m_page-&gt;testTrigger());
</span><span class="lines">@@ -405,6 +344,88 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AsyncScrollingCoordinator::reconcileScrollingState(FrameView&amp; frameView, const FloatPoint&amp; scrollPosition, const LayoutViewportOriginOrOverrideRect&amp; layoutViewportOriginOrOverrideRect, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
+{
+    bool oldProgrammaticScroll = frameView.inProgrammaticScroll();
+    frameView.setInProgrammaticScroll(programmaticScroll);
+
+    WTF::switchOn(layoutViewportOriginOrOverrideRect,
+        [&amp;frameView](Optional&lt;FloatPoint&gt; origin) {
+            if (origin)
+                frameView.setLayoutViewportOrigin(LayoutPoint(origin.value()), FrameView::TriggerLayoutOrNot::No);
+        }, [&amp;frameView](Optional&lt;FloatRect&gt; overrideRect) {
+#if PLATFORM(IOS)
+            if (overrideRect)
+                frameView.setCustomFixedPositionLayoutRect(enclosingIntRect(overrideRect.value()));
+#else
+            UNUSED_PARAM(overrideRect);
+#endif
+        }
+    );
+
+    frameView.setConstrainsScrollingToContentEdge(false);
+    frameView.notifyScrollPositionChanged(roundedIntPoint(scrollPosition));
+    frameView.setConstrainsScrollingToContentEdge(true);
+    frameView.setInProgrammaticScroll(oldProgrammaticScroll);
+
+    if (!programmaticScroll &amp;&amp; scrollingLayerPositionAction == SyncScrollingLayerPosition)
+        syncViewportConstrainedLayerPositions(frameView.rectForFixedPositionLayout());
+
+    GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView);
+    if (!scrollLayer)
+        return;
+
+    GraphicsLayer* counterScrollingLayer = counterScrollingLayerForFrameView(frameView);
+    GraphicsLayer* insetClipLayer = insetClipLayerForFrameView(frameView);
+    GraphicsLayer* contentShadowLayer = contentShadowLayerForFrameView(frameView);
+    GraphicsLayer* scrolledContentsLayer = rootContentLayerForFrameView(frameView);
+    GraphicsLayer* headerLayer = headerLayerForFrameView(frameView);
+    GraphicsLayer* footerLayer = footerLayerForFrameView(frameView);
+
+    ASSERT(frameView.scrollPosition() == roundedIntPoint(scrollPosition));
+    LayoutPoint scrollPositionForFixed = visualViewportEnabled() ? frameView.layoutViewportOrigin() : frameView.scrollPositionForFixedPosition();
+    float topContentInset = frameView.topContentInset();
+
+    FloatPoint positionForInsetClipLayer;
+    if (insetClipLayer)
+        positionForInsetClipLayer = FloatPoint(insetClipLayer-&gt;position().x(), FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
+    FloatPoint positionForContentsLayer = frameView.positionForRootContentLayer();
+    
+    FloatPoint positionForHeaderLayer = FloatPoint(scrollPositionForFixed.x(), FrameView::yPositionForHeaderLayer(scrollPosition, topContentInset));
+    FloatPoint positionForFooterLayer = FloatPoint(scrollPositionForFixed.x(),
+        FrameView::yPositionForFooterLayer(scrollPosition, topContentInset, frameView.totalContentsSize().height(), frameView.footerHeight()));
+
+    if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) {
+        scrollLayer-&gt;setPosition(-frameView.scrollPosition());
+        if (counterScrollingLayer)
+            counterScrollingLayer-&gt;setPosition(scrollPositionForFixed);
+        if (insetClipLayer)
+            insetClipLayer-&gt;setPosition(positionForInsetClipLayer);
+        if (contentShadowLayer)
+            contentShadowLayer-&gt;setPosition(positionForContentsLayer);
+        if (scrolledContentsLayer)
+            scrolledContentsLayer-&gt;setPosition(positionForContentsLayer);
+        if (headerLayer)
+            headerLayer-&gt;setPosition(positionForHeaderLayer);
+        if (footerLayer)
+            footerLayer-&gt;setPosition(positionForFooterLayer);
+    } else {
+        scrollLayer-&gt;syncPosition(-frameView.scrollPosition());
+        if (counterScrollingLayer)
+            counterScrollingLayer-&gt;syncPosition(scrollPositionForFixed);
+        if (insetClipLayer)
+            insetClipLayer-&gt;syncPosition(positionForInsetClipLayer);
+        if (contentShadowLayer)
+            contentShadowLayer-&gt;syncPosition(positionForContentsLayer);
+        if (scrolledContentsLayer)
+            scrolledContentsLayer-&gt;syncPosition(positionForContentsLayer);
+        if (headerLayer)
+            headerLayer-&gt;syncPosition(positionForHeaderLayer);
+        if (footerLayer)
+            footerLayer-&gt;syncPosition(positionForFooterLayer);
+    }
+}
+
</ins><span class="cx"> void AsyncScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea&amp; scrollableArea, ScrollbarOrientation orientation)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="lines">@@ -434,7 +455,7 @@
</span><span class="cx">     m_scrollingStateTree-&gt;clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AsyncScrollingCoordinator::syncChildPositions(const LayoutRect&amp; viewportRect)
</del><ins>+void AsyncScrollingCoordinator::syncViewportConstrainedLayerPositions(const LayoutRect&amp; viewportRect)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_scrollingStateTree-&gt;rootStateNode())
</span><span class="cx">         return;
</span><span class="lines">@@ -443,6 +464,8 @@
</span><span class="cx">     if (!children)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;AsyncScrollingCoordinator::syncChildPositions for viewport rect &quot; &lt;&lt; viewportRect);
+
</ins><span class="cx">     // FIXME: We'll have to traverse deeper into the tree at some point.
</span><span class="cx">     for (auto&amp; child : *children)
</span><span class="cx">         child-&gt;syncLayerPositionForViewportRect(viewportRect);
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -103,6 +103,8 @@
</span><span class="cx">     WEBCORE_EXPORT void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, GraphicsLayer* counterScrollingLayer, GraphicsLayer* insetClipLayer, const ScrollingGeometry* = nullptr) override;
</span><span class="cx">     WEBCORE_EXPORT void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* scrollLayer, GraphicsLayer* scrolledContentsLayer, const ScrollingGeometry* = nullptr) override;
</span><span class="cx">     
</span><ins>+    WEBCORE_EXPORT void reconcileScrollingState(FrameView&amp;, const FloatPoint&amp;, const LayoutViewportOriginOrOverrideRect&amp;, bool programmaticScroll, SetOrSyncScrollingLayerPosition) override;
+
</ins><span class="cx">     bool isRubberBandInProgress() const override;
</span><span class="cx">     void setScrollPinningBehavior(ScrollPinningBehavior) override;
</span><span class="cx"> 
</span><span class="lines">@@ -110,7 +112,7 @@
</span><span class="cx">     bool isScrollSnapInProgress() const override;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void syncChildPositions(const LayoutRect&amp; viewportRect) override;
</del><ins>+    WEBCORE_EXPORT void syncViewportConstrainedLayerPositions(const LayoutRect&amp; viewportRect) override;
</ins><span class="cx">     WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&amp;, ScrollbarOrientation) override;
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void setSynchronousScrollingReasons(SynchronousScrollingReasons) override;
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingCoordinatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/TypeCasts.h&gt;
</span><ins>+#include &lt;wtf/Variant.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(ASYNC_SCROLLING)
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="lines">@@ -117,6 +118,9 @@
</span><span class="cx">     // Should be called whenever the given frame view has been laid out.
</span><span class="cx">     virtual void frameViewLayoutUpdated(FrameView&amp;) { }
</span><span class="cx"> 
</span><ins>+    using LayoutViewportOriginOrOverrideRect = WTF::Variant&lt;Optional&lt;FloatPoint&gt;, Optional&lt;FloatRect&gt;&gt;;
+    virtual void reconcileScrollingState(FrameView&amp;, const FloatPoint&amp;, const LayoutViewportOriginOrOverrideRect&amp;, bool /* programmaticScroll */, SetOrSyncScrollingLayerPosition) { }
+
</ins><span class="cx">     // Should be called whenever the slow repaint objects counter changes between zero and one.
</span><span class="cx">     void frameViewHasSlowRepaintObjectsDidChange(FrameView&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -172,7 +176,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { }
</span><span class="cx">     virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { }
</span><del>-    virtual void syncChildPositions(const LayoutRect&amp;) { }
</del><ins>+    virtual void syncViewportConstrainedLayerPositions(const LayoutRect&amp;) { }
</ins><span class="cx">     virtual String scrollingStateTreeAsText() const;
</span><span class="cx">     virtual bool isRubberBandInProgress() const { return false; }
</span><span class="cx">     virtual bool isScrollSnapInProgress() const { return false; }
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingTreeFrameScrollingNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -121,8 +121,8 @@
</span><span class="cx">     LayoutPoint newLocation = FrameView::computeLayoutViewportOrigin(LayoutRect(visualViewport), LayoutPoint(minLayoutViewportOrigin()), LayoutPoint(maxLayoutViewportOrigin()), layoutViewport);
</span><span class="cx"> 
</span><span class="cx">     if (layoutViewport.location() != newLocation) {
</span><ins>+        layoutViewport.setLocation(newLocation);
</ins><span class="cx">         LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot; new layoutViewport &quot; &lt;&lt; layoutViewport);
</span><del>-        layoutViewport.setLocation(newLocation);
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return layoutViewport;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/Logging.h (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/Logging.h        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/platform/Logging.h        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -79,6 +79,7 @@
</span><span class="cx">     M(StorageAPI) \
</span><span class="cx">     M(SVG) \
</span><span class="cx">     M(TextAutosizing) \
</span><ins>+    M(Tiling) \
</ins><span class="cx">     M(Threading) \
</span><span class="cx">     M(URLParser) \
</span><span class="cx">     M(WebAudio) \
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollView.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollView.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/platform/ScrollView.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -418,7 +418,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ScrollView::setScrollOffset(const ScrollOffset&amp; offset)
</span><span class="cx"> {
</span><del>-    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;ScrollView::setScrollOffset &quot; &lt;&lt; offset);
</del><ins>+    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;\nScrollView::setScrollOffset &quot; &lt;&lt; offset);
</ins><span class="cx"> 
</span><span class="cx">     IntPoint constrainedOffset = offset;
</span><span class="cx">     if (constrainsScrollingToContentEdge())
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaTileControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/TileController.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/TileController.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/platform/graphics/ca/TileController.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -451,7 +451,7 @@
</span><span class="cx">     FloatRect coverageBounds = boundsForSize(newSize);
</span><span class="cx">     
</span><span class="cx">     FloatRect coverage = expandRectWithinRect(visibleRect, coverageSize, coverageBounds);
</span><del>-    LOG_WITH_STREAM(Scrolling, stream &lt;&lt; &quot;TileController::computeTileCoverageRect newSize=&quot; &lt;&lt; newSize &lt;&lt; &quot; mode &quot; &lt;&lt; m_tileCoverage &lt;&lt; &quot; expanded to &quot; &lt;&lt; coverageSize &lt;&lt; &quot; bounds with margin &quot; &lt;&lt; coverageBounds &lt;&lt; &quot; coverage &quot; &lt;&lt; coverage);
</del><ins>+    LOG_WITH_STREAM(Tiling, stream &lt;&lt; &quot;TileController::computeTileCoverageRect newSize=&quot; &lt;&lt; newSize &lt;&lt; &quot; mode &quot; &lt;&lt; m_tileCoverage &lt;&lt; &quot; expanded to &quot; &lt;&lt; coverageSize &lt;&lt; &quot; bounds with margin &quot; &lt;&lt; coverageBounds &lt;&lt; &quot; coverage &quot; &lt;&lt; coverage);
</ins><span class="cx">     coverageRect.unite(coverage);
</span><span class="cx"> #endif
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -824,6 +824,8 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(this == renderer().view().layer());
</span><span class="cx"> 
</span><ins>+    LOG(Scrolling, &quot;RenderLayer::updateLayerPositionsAfterDocumentScroll&quot;);
+
</ins><span class="cx">     RenderGeometryMap geometryMap(UseTransforms);
</span><span class="cx">     updateLayerPositionsAfterScroll(&amp;geometryMap);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebKit2/ChangeLog        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-11-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        [iOS WK2] Share some code with Mac for post-async-scroll state reconciliation
+        https://bugs.webkit.org/show_bug.cgi?id=164694
+
+        Reviewed by Zalan Bujtas.
+
+        Rather than calling FrameView directly, call reconcileScrollingState() on the scrolling
+        coordinator.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::updateVisibleContentRects):
+
</ins><span class="cx"> 2016-11-12  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Automation: terminate the automation session if the web process crashes
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (208661 => 208662)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2016-11-13 03:08:52 UTC (rev 208661)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2016-11-13 03:24:27 UTC (rev 208662)
</span><span class="lines">@@ -3060,9 +3060,12 @@
</span><span class="cx">     if (!visibleContentRectUpdateInfo.isChangingObscuredInsetsInteractively())
</span><span class="cx">         frameView.setCustomSizeForResizeEvent(expandedIntSize(visibleContentRectUpdateInfo.unobscuredRectInScrollViewCoordinates().size()));
</span><span class="cx"> 
</span><del>-    frameView.setConstrainsScrollingToContentEdge(false);
-    frameView.setScrollOffset(frameView.scrollOffsetFromPosition(scrollPosition));
-    frameView.setConstrainsScrollingToContentEdge(true);
</del><ins>+    if (ScrollingCoordinator* scrollingCoordinator = this-&gt;scrollingCoordinator()) {
+        Optional&lt;FloatRect&gt; customFixedPositionRect;
+        if (m_isInStableState)
+            customFixedPositionRect = visibleContentRectUpdateInfo.customFixedPositionRect();
+        scrollingCoordinator-&gt;reconcileScrollingState(frameView, scrollPosition, customFixedPositionRect, false, SetOrSyncScrollingLayerPosition::SyncScrollingLayerPosition);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebPage::willStartUserTriggeredZooming()
</span></span></pre>
</div>
</div>

</body>
</html>