<!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>[168338] trunk/Source</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/168338">168338</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2014-05-05 18:10:30 -0700 (Mon, 05 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS WK2] Flickery scrolling inside overflow-scrolling: touch
https://bugs.webkit.org/show_bug.cgi?id=132591
&lt;rdar://problem/16760466&gt;

Reviewed by Tim Horton.

Source/WebCore:

Avoid triggering layer tree commits that touch the layer's boundsOrigin
while the user is scrolling in the UI process.

Fix the WKOverflowScrollViewDelegate to pass along an &quot;inUserInteration&quot;
flag to the ScrollingTree to say that we're in the middle of a user interaction
(and also to send a final non-interactive update). That gets passed along
to the web process, and turned into &quot;SyncScrollingLayerPosition&quot; update.
AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() consults
this, and uses it to set a flag on the ScrollableArea to say that the scroll
is a user scroll.

RenderLayerBacking then makes use of this (in existing code, shared with WK1)
to avoid triggering layer bounds setting. Instead, it now just calls syncBoundsOrigin(),
which updates the GraphicsLayer without touching platform layers. This is necessary
so that GraphicsLayer geometry is up-to-date (used for tiled layer visibility
computations).

Finally, a hack in GraphicsLayerCA::computeVisibleRect() is conditionalized
for WebKit1 by checking the type of platform layer.

* WebCore.exp.in:
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::scrollPositionChangedViaDelegatedScrolling):
* page/scrolling/ScrollingTree.h:
* platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::syncBoundsOrigin):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::computeVisibleRect):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):

Source/WebKit2:

Avoid triggering layer tree commits that touch the layer's boundsOrigin
while the user is scrolling in the UI process.

Fix the WKOverflowScrollViewDelegate to pass along an &quot;inUserInteration&quot;
flag to the ScrollingTree to say that we're in the middle of a user interaction
(and also to send a final non-interactive update). That gets passed along
to the web process, and turned into &quot;SyncScrollingLayerPosition&quot; update.
AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() consults
this, and uses it to set a flag on the ScrollableArea to say that the scroll
is a user scroll.

RenderLayerBacking then makes use of this (in existing code, shared with WK1)
to avoid triggering layer bounds setting. Instead, it now just calls syncBoundsOrigin(),
which updates the GraphicsLayer without touching platform layers. This is necessary
so that GraphicsLayer geometry is up-to-date (used for tiled layer visibility
computations).

Finally, a hack in GraphicsLayerCA::computeVisibleRect() is conditionalized
for WebKit1 by checking the type of platform layer.

* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::rootScrollingNodeID):
(WebKit::RemoteScrollingCoordinatorProxy::isPointInNonFastScrollableRegion):
(WebKit::RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling):
(WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
* UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
* UIProcess/Scrolling/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
* UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
* UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
(-[WKOverflowScrollViewDelegate scrollViewDidScroll:]):
(-[WKOverflowScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]):
(-[WKOverflowScrollViewDelegate scrollViewDidEndDecelerating:]):
(WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollViewDidScroll):
* WebProcess/Scrolling/RemoteScrollingCoordinator.h:
* WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in:
* WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
(WebKit::RemoteScrollingCoordinator::scrollPositionChangedForNode):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp">trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingTreecpp">trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingTreeh">trunk/Source/WebCore/page/scrolling/ScrollingTree.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollableAreah">trunk/Source/WebCore/platform/ScrollableArea.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsGraphicsLayerh">trunk/Source/WebCore/platform/graphics/GraphicsLayer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp">trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessScrollingRemoteScrollingCoordinatorProxycpp">trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessScrollingRemoteScrollingCoordinatorProxyh">trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessScrollingRemoteScrollingTreecpp">trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessScrollingiosScrollingTreeOverflowScrollingNodeIOSh">trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessScrollingiosScrollingTreeOverflowScrollingNodeIOSmm">trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatorh">trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatormessagesin">trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in</a></li>
<li><a href="#trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatormm">trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/ChangeLog        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2014-05-05  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        [iOS WK2] Flickery scrolling inside overflow-scrolling: touch
+        https://bugs.webkit.org/show_bug.cgi?id=132591
+        &lt;rdar://problem/16760466&gt;
+
+        Reviewed by Tim Horton.
+
+        Avoid triggering layer tree commits that touch the layer's boundsOrigin
+        while the user is scrolling in the UI process.
+        
+        Fix the WKOverflowScrollViewDelegate to pass along an &quot;inUserInteration&quot;
+        flag to the ScrollingTree to say that we're in the middle of a user interaction
+        (and also to send a final non-interactive update). That gets passed along
+        to the web process, and turned into &quot;SyncScrollingLayerPosition&quot; update.
+        AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() consults
+        this, and uses it to set a flag on the ScrollableArea to say that the scroll
+        is a user scroll.
+        
+        RenderLayerBacking then makes use of this (in existing code, shared with WK1)
+        to avoid triggering layer bounds setting. Instead, it now just calls syncBoundsOrigin(),
+        which updates the GraphicsLayer without touching platform layers. This is necessary
+        so that GraphicsLayer geometry is up-to-date (used for tiled layer visibility
+        computations).
+        
+        Finally, a hack in GraphicsLayerCA::computeVisibleRect() is conditionalized
+        for WebKit1 by checking the type of platform layer.
+
+        * WebCore.exp.in:
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::scrollPositionChangedViaDelegatedScrolling):
+        * page/scrolling/ScrollingTree.h:
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::syncBoundsOrigin):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::computeVisibleRect):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+
</ins><span class="cx"> 2014-05-05  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Stop using BlobData on client side
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -2760,7 +2760,7 @@
</span><span class="cx"> __ZN7WebCore13ScrollingTree35shouldHandleWheelEventSynchronouslyERKNS_18PlatformWheelEventE
</span><span class="cx"> __ZN7WebCore13ScrollingTree36viewportChangedViaDelegatedScrollingEyRKNS_9FloatRectEd
</span><span class="cx"> __ZN7WebCore13ScrollingTree37setScrollingPerformanceLoggingEnabledEb
</span><del>-__ZN7WebCore13ScrollingTree42scrollPositionChangedViaDelegatedScrollingEyRKNS_10FloatPointE
</del><ins>+__ZN7WebCore13ScrollingTree42scrollPositionChangedViaDelegatedScrollingEyRKNS_10FloatPointEb
</ins><span class="cx"> __ZN7WebCore13ScrollingTreeC2Ev
</span><span class="cx"> __ZN7WebCore13ScrollingTreeD1Ev
</span><span class="cx"> __ZN7WebCore13ScrollingTreeD2Ev
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingAsyncScrollingCoordinatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -254,8 +254,11 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Overflow-scroll area.
</span><del>-    if (ScrollableArea* scrollableArea = frameView-&gt;scrollableAreaForScrollLayerID(scrollingNodeID))
</del><ins>+    if (ScrollableArea* scrollableArea = frameView-&gt;scrollableAreaForScrollLayerID(scrollingNodeID)) {
+        scrollableArea-&gt;setIsUserScroll(scrollingLayerPositionAction == SyncScrollingLayerPosition);
</ins><span class="cx">         scrollableArea-&gt;scrollToOffsetWithoutAnimation(scrollPosition);
</span><ins>+        scrollableArea-&gt;setIsUserScroll(false);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AsyncScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea* scrollableArea, ScrollbarOrientation orientation)
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">     toScrollingTreeScrollingNode(node)-&gt;updateLayersAfterViewportChange(viewportRect, scale);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingTree::scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatPoint&amp; scrollPosition)
</del><ins>+void ScrollingTree::scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatPoint&amp; scrollPosition, bool inUserInteration)
</ins><span class="cx"> {
</span><span class="cx">     ScrollingTreeNode* node = nodeForID(nodeID);
</span><span class="cx">     if (!node)
</span><span class="lines">@@ -123,7 +123,7 @@
</span><span class="cx">     toScrollingTreeScrollingNode(node)-&gt;updateLayersAfterDelegatedScroll(scrollPosition);
</span><span class="cx"> 
</span><span class="cx">     // Update GraphicsLayers and scroll state.
</span><del>-    scrollingTreeNodeDidScroll(nodeID, scrollPosition);
</del><ins>+    scrollingTreeNodeDidScroll(nodeID, scrollPosition, inUserInteration ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollingTree::commitNewTreeState(PassOwnPtr&lt;ScrollingStateTree&gt; scrollingStateTree)
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingTreeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Delegated scrolling has scrolled a node. Update layer positions on descendant tree nodes,
</span><span class="cx">     // and call scrollingTreeNodeDidScroll().
</span><del>-    virtual void scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatPoint&amp; scrollPosition);
</del><ins>+    virtual void scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatPoint&amp; scrollPosition, bool inUserInteration);
</ins><span class="cx"> 
</span><span class="cx">     FloatPoint mainFrameScrollPosition();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollableAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollableArea.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollableArea.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/platform/ScrollableArea.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -68,8 +68,8 @@
</span><span class="cx">     virtual void didStartScroll() { }
</span><span class="cx">     virtual void didEndScroll() { }
</span><span class="cx">     virtual void didUpdateScroll() { }
</span><ins>+#endif
</ins><span class="cx">     virtual void setIsUserScroll(bool) { }
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     // Functions for controlling if you can scroll past the end of the document.
</span><span class="cx">     bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsLayer.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsLayer.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/platform/graphics/GraphicsLayer.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -289,7 +289,7 @@
</span><span class="cx"> 
</span><span class="cx">     // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
</span><span class="cx">     virtual void syncPosition(const FloatPoint&amp; p) { m_position = p; }
</span><del>-    
</del><ins>+
</ins><span class="cx">     // Anchor point: (0, 0) is top left, (1, 1) is bottom right. The anchor point
</span><span class="cx">     // affects the origin of the transforms.
</span><span class="cx">     const FloatPoint3D&amp; anchorPoint() const { return m_anchorPoint; }
</span><span class="lines">@@ -303,6 +303,9 @@
</span><span class="cx">     const FloatPoint&amp; boundsOrigin() const { return m_boundsOrigin; }
</span><span class="cx">     virtual void setBoundsOrigin(const FloatPoint&amp; origin) { m_boundsOrigin = origin; }
</span><span class="cx"> 
</span><ins>+    // For platforms that move underlying platform layers on a different thread for scrolling; just update the GraphicsLayer state.
+    virtual void syncBoundsOrigin(const FloatPoint&amp; origin) { m_boundsOrigin = origin; }
+
</ins><span class="cx">     const TransformationMatrix&amp; transform() const { return m_transform; }
</span><span class="cx">     virtual void setTransform(const TransformationMatrix&amp; t) { m_transform = t; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscaGraphicsLayerCAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -1147,8 +1147,9 @@
</span><span class="cx">     FloatRect clipRectForChildren = state.mappedQuad(&amp;mapWasClamped).boundingBox();
</span><span class="cx">     FloatPoint boundsOrigin = m_boundsOrigin;
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    // UIKit may be changing layer bounds behind our back in overflow-scroll layers, so use the layer's origin.
-    boundsOrigin = m_layer-&gt;bounds().location();
</del><ins>+    // In WK1, UIKit may be changing layer bounds behind our back in overflow-scroll layers, so use the layer's origin.
+    if (m_layer-&gt;isPlatformCALayerMac())
+        boundsOrigin = m_layer-&gt;bounds().location();
</ins><span class="cx"> #endif
</span><span class="cx">     clipRectForChildren.move(boundsOrigin.x(), boundsOrigin.y());
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -924,8 +924,8 @@
</span><span class="cx">         bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer-&gt;offsetFromRenderer();
</span><span class="cx"> 
</span><span class="cx">         if (m_owningLayer.isInUserScroll()) {
</span><del>-            // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause
-            // jitter. Set a flag to ensure that we sync up later.
</del><ins>+            // If scrolling is happening externally, we don't want to touch the layer bounds origin here because that will cause jitter.
+            m_scrollingLayer-&gt;syncBoundsOrigin(FloatPoint(scrollOffset.width(), scrollOffset.height()));
</ins><span class="cx">             m_owningLayer.setRequiresScrollBoundsOriginUpdate(true);
</span><span class="cx">         } else {
</span><span class="cx">             // Note that we implement the contents offset via the bounds origin on this layer, rather than a position on the sublayer.
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/ChangeLog        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2014-05-05  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        [iOS WK2] Flickery scrolling inside overflow-scrolling: touch
+        https://bugs.webkit.org/show_bug.cgi?id=132591
+        &lt;rdar://problem/16760466&gt;
+
+        Reviewed by Tim Horton.
+        
+        Avoid triggering layer tree commits that touch the layer's boundsOrigin
+        while the user is scrolling in the UI process.
+        
+        Fix the WKOverflowScrollViewDelegate to pass along an &quot;inUserInteration&quot;
+        flag to the ScrollingTree to say that we're in the middle of a user interaction
+        (and also to send a final non-interactive update). That gets passed along
+        to the web process, and turned into &quot;SyncScrollingLayerPosition&quot; update.
+        AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() consults
+        this, and uses it to set a flag on the ScrollableArea to say that the scroll
+        is a user scroll.
+        
+        RenderLayerBacking then makes use of this (in existing code, shared with WK1)
+        to avoid triggering layer bounds setting. Instead, it now just calls syncBoundsOrigin(),
+        which updates the GraphicsLayer without touching platform layers. This is necessary
+        so that GraphicsLayer geometry is up-to-date (used for tiled layer visibility
+        computations).
+        
+        Finally, a hack in GraphicsLayerCA::computeVisibleRect() is conditionalized
+        for WebKit1 by checking the type of platform layer.
+
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::rootScrollingNodeID):
+        (WebKit::RemoteScrollingCoordinatorProxy::isPointInNonFastScrollableRegion):
+        (WebKit::RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling):
+        (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll):
+        * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+        * UIProcess/Scrolling/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::scrollingTreeNodeDidScroll):
+        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h:
+        * UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
+        (-[WKOverflowScrollViewDelegate scrollViewDidScroll:]):
+        (-[WKOverflowScrollViewDelegate scrollViewDidEndDragging:willDecelerate:]):
+        (-[WKOverflowScrollViewDelegate scrollViewDidEndDecelerating:]):
+        (WebKit::ScrollingTreeOverflowScrollingNodeIOS::scrollViewDidScroll):
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.h:
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in:
+        * WebProcess/Scrolling/RemoteScrollingCoordinator.mm:
+        (WebKit::RemoteScrollingCoordinator::scrollPositionChangedForNode):
+
</ins><span class="cx"> 2014-05-05  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Stop using BlobData on client side
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessScrollingRemoteScrollingCoordinatorProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebCore::ScrollingNodeID RemoteScrollingCoordinatorProxy::rootScrollingNodeID() const
</del><ins>+ScrollingNodeID RemoteScrollingCoordinatorProxy::rootScrollingNodeID() const
</ins><span class="cx"> {
</span><span class="cx">     if (!m_scrollingTree-&gt;rootNode())
</span><span class="cx">         return 0;
</span><span class="lines">@@ -139,25 +139,25 @@
</span><span class="cx">     return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool RemoteScrollingCoordinatorProxy::isPointInNonFastScrollableRegion(const WebCore::IntPoint&amp; p) const
</del><ins>+bool RemoteScrollingCoordinatorProxy::isPointInNonFastScrollableRegion(const IntPoint&amp; p) const
</ins><span class="cx"> {
</span><span class="cx">     return m_scrollingTree-&gt;isPointInNonFastScrollableRegion(p);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatRect&amp; viewportRect, double scale)
</del><ins>+void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const FloatRect&amp; viewportRect, double scale)
</ins><span class="cx"> {
</span><span class="cx">     m_scrollingTree-&gt;viewportChangedViaDelegatedScrolling(nodeID, viewportRect, scale);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // This comes from the scrolling tree.
</span><del>-void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID scrolledNodeID, const WebCore::FloatPoint&amp; newScrollPosition)
</del><ins>+void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint&amp; newScrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
</ins><span class="cx"> {
</span><span class="cx">     // Scroll updates for the main frame are sent via WebPageProxy::updateVisibleContentRects()
</span><span class="cx">     // so don't send them here.
</span><span class="cx">     if (!m_propagatesMainFrameScrolls &amp;&amp; scrolledNodeID == rootScrollingNodeID())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition));
</del><ins>+    m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint&amp; scrollPosition, bool representsProgrammaticScroll)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessScrollingRemoteScrollingCoordinatorProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     virtual ~RemoteScrollingCoordinatorProxy();
</span><span class="cx">     
</span><span class="cx">     // Inform the web process that the scroll position changed (called from the scrolling tree)
</span><del>-    void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint&amp; newScrollPosition);
</del><ins>+    void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint&amp; newScrollPosition, WebCore::SetOrSyncScrollingLayerPosition);
</ins><span class="cx">     void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint&amp; scrollPosition, bool representsProgrammaticScroll);
</span><span class="cx"> 
</span><span class="cx">     bool isPointInNonFastScrollableRegion(const WebCore::IntPoint&amp;) const;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessScrollingRemoteScrollingTreecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -77,9 +77,9 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint&amp; scrollPosition, SetOrSyncScrollingLayerPosition)
</del><ins>+void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint&amp; scrollPosition, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction)
</ins><span class="cx"> {
</span><del>-    m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition);
</del><ins>+    m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition, scrollingLayerPositionAction);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint&amp; scrollPosition, bool representsProgrammaticScroll)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessScrollingiosScrollingTreeOverflowScrollingNodeIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx">     static PassOwnPtr&lt;ScrollingTreeOverflowScrollingNodeIOS&gt; create(WebCore::ScrollingTree&amp;, WebCore::ScrollingNodeID);
</span><span class="cx">     virtual ~ScrollingTreeOverflowScrollingNodeIOS();
</span><span class="cx"> 
</span><del>-    void scrollViewDidScroll(const WebCore::FloatPoint&amp;);
</del><ins>+    void scrollViewDidScroll(const WebCore::FloatPoint&amp;, bool inUserInteration);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     ScrollingTreeOverflowScrollingNodeIOS(WebCore::ScrollingTree&amp;, WebCore::ScrollingNodeID);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessScrollingiosScrollingTreeOverflowScrollingNodeIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/ios/ScrollingTreeOverflowScrollingNodeIOS.mm        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)scrollViewDidScroll:(UIScrollView *)scrollView
</span><span class="cx"> {
</span><del>-    _scrollingTreeNode-&gt;scrollViewDidScroll(scrollView.contentOffset);
</del><ins>+    _scrollingTreeNode-&gt;scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
</span><span class="lines">@@ -68,13 +68,18 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)willDecelerate
</span><span class="cx"> {
</span><del>-    if (!willDecelerate)
</del><ins>+    if (_inUserInteraction &amp;&amp; !willDecelerate) {
</ins><span class="cx">         _inUserInteraction = NO;
</span><ins>+        _scrollingTreeNode-&gt;scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
</span><span class="cx"> {
</span><del>-    _inUserInteraction = NO;
</del><ins>+    if (_inUserInteraction) {
+        _inUserInteraction = NO;
+        _scrollingTreeNode-&gt;scrollViewDidScroll(scrollView.contentOffset, _inUserInteraction);
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="lines">@@ -145,9 +150,9 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingTreeOverflowScrollingNodeIOS::scrollViewDidScroll(const FloatPoint&amp; scrollPosition)
</del><ins>+void ScrollingTreeOverflowScrollingNodeIOS::scrollViewDidScroll(const FloatPoint&amp; scrollPosition, bool inUserInteration)
</ins><span class="cx"> {
</span><del>-    scrollingTree().scrollPositionChangedViaDelegatedScrolling(scrollingNodeID(), scrollPosition);
</del><ins>+    scrollingTree().scrollPositionChangedViaDelegatedScrolling(scrollingNodeID(), scrollPosition, inUserInteration);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.h (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.h        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.h        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">     virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&amp;) override;
</span><span class="cx">     
</span><span class="cx">     // Respond to UI process changes.
</span><del>-    void scrollPositionChangedForNode(WebCore::ScrollingNodeID, const WebCore::FloatPoint&amp; scrollPosition);
</del><ins>+    void scrollPositionChangedForNode(WebCore::ScrollingNodeID, const WebCore::FloatPoint&amp; scrollPosition, bool syncLayerPosition);
</ins><span class="cx"> 
</span><span class="cx">     WebPage* m_webPage;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatormessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.messages.in        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx"> #if ENABLE(ASYNC_SCROLLING)
</span><span class="cx"> 
</span><span class="cx"> messages -&gt; RemoteScrollingCoordinator {
</span><del>-    ScrollPositionChangedForNode(uint64_t nodeID, WebCore::FloatPoint scrollPosition);
</del><ins>+    ScrollPositionChangedForNode(uint64_t nodeID, WebCore::FloatPoint scrollPosition, bool syncLayerPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(ASYNC_SCROLLING)
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessScrollingRemoteScrollingCoordinatormm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.mm (168337 => 168338)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.mm        2014-05-06 01:10:06 UTC (rev 168337)
+++ trunk/Source/WebKit2/WebProcess/Scrolling/RemoteScrollingCoordinator.mm        2014-05-06 01:10:30 UTC (rev 168338)
</span><span class="lines">@@ -91,9 +91,9 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Notification from the UI process that we scrolled.
</span><del>-void RemoteScrollingCoordinator::scrollPositionChangedForNode(ScrollingNodeID nodeID, const FloatPoint&amp; scrollPosition)
</del><ins>+void RemoteScrollingCoordinator::scrollPositionChangedForNode(ScrollingNodeID nodeID, const FloatPoint&amp; scrollPosition, bool syncLayerPosition)
</ins><span class="cx"> {
</span><del>-    scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, false /* FIXME */, SyncScrollingLayerPosition);
</del><ins>+    scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, false /* FIXME */, syncLayerPosition ? SyncScrollingLayerPosition : SetScrollingLayerPosition);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre>
</div>
</div>

</body>
</html>