Implement asynchronous frame scrolling for iOS
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Jan 2019 20:07:44 +0000 (20:07 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 18 Jan 2019 20:07:44 +0000 (20:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193539
<rdar://problem/47379873>

Reviewed by Simon Fraser.

Source/WebCore:

This patch implements UIScrollView based frame scrolling on iOS, enabled by the "Async Frame Scrolling"
internal setting (still off by default).

* page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h:
(WebCore::ScrollingTreeFrameScrollingNodeIOS::scrollLayer const): Deleted.
* page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
(WebCore::ScrollingTreeFrameScrollingNodeIOS::setScrollPosition):

Export ScrollingTreeFrameScrollingNodeIOS.

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::visibleRectForLayerFlushing const):
(WebCore::RenderLayerCompositor::frameViewDidChangeSize):
(WebCore::RenderLayerCompositor::updateScrollLayerClipping):

If we don't have a separate clip layer, just resize and position the scroll layer.

(WebCore::RenderLayerCompositor::updateRootLayerPosition):
(WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
(WebCore::RenderLayerCompositor::ensureRootLayer):

Use GraphicsLayer::Type::Scrolling as the scroll layer type when async frame scrolling is enabled.
Don't create a separate clip layer since the scroll layer will handle clipping.

* rendering/RenderLayerCompositor.h:

Source/WebKit:

Add a scrolling node type that can handle UIScrollView backed frames.
It basically just instantiates and forwards to the existing ScrollingTreeScrollingNodeDelegateIOS.

* UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::createScrollingTreeNode):
* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
* UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h: Added.
* UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm: Added.
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::create):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::ScrollingTreeFrameScrollingNodeRemoteIOS):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::~ScrollingTreeFrameScrollingNodeRemoteIOS):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateBeforeChildren):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterAncestorChange):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::scrollPosition const):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::setScrollLayerPosition):
(WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterDelegatedScroll):
* WebKit.xcodeproj/project.pbxproj:

LayoutTests:

* platform/ios-wk2/compositing/tiling/tiled-drawing-async-frame-scrolling-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240162 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/ios-wk2/compositing/tiling/tiled-drawing-async-frame-scrolling-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h
Source/WebCore/page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebKit/ChangeLog
Source/WebKit/SourcesCocoa.txt
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h [new file with mode: 0644]
Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm [new file with mode: 0644]
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index 65fc352..7978813 100644 (file)
@@ -1,3 +1,13 @@
+2019-01-18  Antti Koivisto  <antti@apple.com>
+
+        Implement asynchronous frame scrolling for iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193539
+        <rdar://problem/47379873>
+
+        Reviewed by Simon Fraser.
+
+        * platform/ios-wk2/compositing/tiling/tiled-drawing-async-frame-scrolling-expected.txt:
+
 2019-01-18  Ali Juma  <ajuma@chromium.org>
 
         FetchResponse::url should return the empty string for tainted responses
index 6eb430d..b38c738 100644 (file)
               (contentsScale 2.00)
               (children 1
                 (GraphicsLayer
-                  (anchor 0.00 0.00)
                   (bounds 300.00 150.00)
                   (backingStoreAttached 1)
                   (visible rect 0.00, 0.00 300.00 x 150.00)
-                  (coverage rect 0.00, 0.00 300.00 x 150.00)
+                  (coverage rect -10.00, -10.00 800.00 x 600.00)
                   (intersects coverage rect 1)
                   (contentsScale 2.00)
                   (children 1
                     (GraphicsLayer
-                      (backingStoreAttached 0)
-                      (visible rect 0.00, 0.00 0.00 x 0.00)
-                      (coverage rect 0.00, 0.00 300.00 x 150.00)
-                      (intersects coverage rect 0)
+                      (anchor 0.00 0.00)
+                      (bounds 400.00 300.00)
+                      (backingStoreAttached 1)
+                      (visible rect 0.00, 0.00 400.00 x 300.00)
+                      (coverage rect 0.00, 0.00 400.00 x 300.00)
+                      (intersects coverage rect 1)
                       (contentsScale 2.00)
                       (children 1
                         (GraphicsLayer
-                          (anchor 0.00 0.00)
                           (bounds 400.00 300.00)
+                          (drawsContent 1)
                           (backingStoreAttached 1)
-                          (visible rect 0.00, 0.00 300.00 x 150.00)
-                          (coverage rect 0.00, 0.00 300.00 x 150.00)
+                          (visible rect 0.00, 0.00 400.00 x 300.00)
+                          (coverage rect 0.00, 0.00 400.00 x 300.00)
                           (intersects coverage rect 1)
                           (contentsScale 2.00)
+                          (tile cache coverage 0, 0 400 x 300)
+                          (tile size 512 x 512)
+                          (top left tile 0, 0 tiles grid 1 x 1)
+                          (in window 1)
                           (children 1
                             (GraphicsLayer
-                              (bounds 400.00 300.00)
-                              (drawsContent 1)
-                              (backingStoreAttached 1)
-                              (visible rect 0.00, 0.00 300.00 x 150.00)
-                              (coverage rect 0.00, 0.00 300.00 x 150.00)
-                              (intersects coverage rect 1)
+                              (backingStoreAttached 0)
+                              (visible rect 0.00, 0.00 0.00 x 0.00)
+                              (coverage rect 0.00, 0.00 400.00 x 300.00)
+                              (intersects coverage rect 0)
                               (contentsScale 2.00)
-                              (tile cache coverage 0, 0 400 x 300)
-                              (tile size 512 x 512)
-                              (top left tile 0, 0 tiles grid 1 x 1)
-                              (in window 1)
-                              (children 1
-                                (GraphicsLayer
-                                  (backingStoreAttached 0)
-                                  (visible rect 0.00, 0.00 0.00 x 0.00)
-                                  (coverage rect 0.00, 0.00 300.00 x 150.00)
-                                  (intersects coverage rect 0)
-                                  (contentsScale 2.00)
-                                )
-                              )
                             )
                           )
                         )
               (contentsScale 2.00)
               (children 1
                 (GraphicsLayer
-                  (anchor 0.00 0.00)
                   (bounds 300.00 150.00)
                   (backingStoreAttached 1)
                   (visible rect 0.00, 0.00 300.00 x 150.00)
-                  (coverage rect 0.00, 0.00 300.00 x 150.00)
+                  (coverage rect -318.00, -10.00 800.00 x 600.00)
                   (intersects coverage rect 1)
                   (contentsScale 2.00)
                   (children 1
                     (GraphicsLayer
-                      (backingStoreAttached 0)
-                      (visible rect 0.00, 0.00 0.00 x 0.00)
-                      (coverage rect 0.00, 0.00 300.00 x 150.00)
-                      (intersects coverage rect 0)
+                      (anchor 0.00 0.00)
+                      (bounds 400.00 300.00)
+                      (backingStoreAttached 1)
+                      (visible rect 0.00, 0.00 400.00 x 300.00)
+                      (coverage rect 0.00, 0.00 400.00 x 300.00)
+                      (intersects coverage rect 1)
                       (contentsScale 2.00)
                       (children 1
                         (GraphicsLayer
-                          (anchor 0.00 0.00)
                           (bounds 400.00 300.00)
+                          (drawsContent 1)
                           (backingStoreAttached 1)
-                          (visible rect 0.00, 0.00 300.00 x 150.00)
-                          (coverage rect 0.00, 0.00 300.00 x 150.00)
+                          (visible rect 0.00, 0.00 400.00 x 300.00)
+                          (coverage rect 0.00, 0.00 400.00 x 300.00)
                           (intersects coverage rect 1)
                           (contentsScale 2.00)
+                          (tile cache coverage 0, 0 400 x 300)
+                          (tile size 512 x 512)
+                          (top left tile 0, 0 tiles grid 1 x 1)
+                          (in window 1)
                           (children 1
                             (GraphicsLayer
-                              (bounds 400.00 300.00)
-                              (drawsContent 1)
-                              (backingStoreAttached 1)
-                              (visible rect 0.00, 0.00 300.00 x 150.00)
-                              (coverage rect 0.00, 0.00 300.00 x 150.00)
-                              (intersects coverage rect 1)
+                              (backingStoreAttached 0)
+                              (visible rect 0.00, 0.00 0.00 x 0.00)
+                              (coverage rect 0.00, 0.00 400.00 x 300.00)
+                              (intersects coverage rect 0)
                               (contentsScale 2.00)
-                              (tile cache coverage 0, 0 400 x 300)
-                              (tile size 512 x 512)
-                              (top left tile 0, 0 tiles grid 1 x 1)
-                              (in window 1)
-                              (children 1
-                                (GraphicsLayer
-                                  (backingStoreAttached 0)
-                                  (visible rect 0.00, 0.00 0.00 x 0.00)
-                                  (coverage rect 0.00, 0.00 300.00 x 150.00)
-                                  (intersects coverage rect 0)
-                                  (contentsScale 2.00)
-                                )
-                              )
                             )
                           )
                         )
               (contentsScale 2.00)
               (children 1
                 (GraphicsLayer
-                  (anchor 0.00 0.00)
                   (bounds 300.00 150.00)
                   (backingStoreAttached 1)
                   (visible rect 0.00, 0.00 300.00 x 150.00)
-                  (coverage rect 0.00, 0.00 300.00 x 150.00)
+                  (coverage rect -10.00, -169.00 800.00 x 600.00)
                   (intersects coverage rect 1)
                   (contentsScale 2.00)
                   (children 1
                     (GraphicsLayer
-                      (backingStoreAttached 0)
-                      (visible rect 0.00, 0.00 0.00 x 0.00)
-                      (coverage rect 0.00, 0.00 300.00 x 150.00)
-                      (intersects coverage rect 0)
+                      (anchor 0.00 0.00)
+                      (bounds 400.00 300.00)
+                      (backingStoreAttached 1)
+                      (visible rect 0.00, 0.00 400.00 x 300.00)
+                      (coverage rect 0.00, 0.00 400.00 x 300.00)
+                      (intersects coverage rect 1)
                       (contentsScale 2.00)
                       (children 1
                         (GraphicsLayer
-                          (anchor 0.00 0.00)
                           (bounds 400.00 300.00)
+                          (drawsContent 1)
                           (backingStoreAttached 1)
-                          (visible rect 0.00, 0.00 300.00 x 150.00)
-                          (coverage rect 0.00, 0.00 300.00 x 150.00)
+                          (visible rect 0.00, 0.00 400.00 x 300.00)
+                          (coverage rect 0.00, 0.00 400.00 x 300.00)
                           (intersects coverage rect 1)
                           (contentsScale 2.00)
+                          (tile cache coverage 0, 0 400 x 300)
+                          (tile size 512 x 512)
+                          (top left tile 0, 0 tiles grid 1 x 1)
+                          (in window 1)
                           (children 1
                             (GraphicsLayer
-                              (bounds 400.00 300.00)
-                              (drawsContent 1)
-                              (backingStoreAttached 1)
-                              (visible rect 0.00, 0.00 300.00 x 150.00)
-                              (coverage rect 0.00, 0.00 300.00 x 150.00)
-                              (intersects coverage rect 1)
+                              (backingStoreAttached 0)
+                              (visible rect 0.00, 0.00 0.00 x 0.00)
+                              (coverage rect 0.00, 0.00 400.00 x 300.00)
+                              (intersects coverage rect 0)
                               (contentsScale 2.00)
-                              (tile cache coverage 0, 0 400 x 300)
-                              (tile size 512 x 512)
-                              (top left tile 0, 0 tiles grid 1 x 1)
-                              (in window 1)
-                              (children 1
-                                (GraphicsLayer
-                                  (backingStoreAttached 0)
-                                  (visible rect 0.00, 0.00 0.00 x 0.00)
-                                  (coverage rect 0.00, 0.00 300.00 x 150.00)
-                                  (intersects coverage rect 0)
-                                  (contentsScale 2.00)
-                                )
-                              )
                             )
                           )
                         )
index 89c045b..1d16aef 100644 (file)
@@ -1,3 +1,37 @@
+2019-01-18  Antti Koivisto  <antti@apple.com>
+
+        Implement asynchronous frame scrolling for iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193539
+        <rdar://problem/47379873>
+
+        Reviewed by Simon Fraser.
+
+        This patch implements UIScrollView based frame scrolling on iOS, enabled by the "Async Frame Scrolling"
+        internal setting (still off by default).
+
+        * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.h:
+        (WebCore::ScrollingTreeFrameScrollingNodeIOS::scrollLayer const): Deleted.
+        * page/scrolling/ios/ScrollingTreeFrameScrollingNodeIOS.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeIOS::setScrollPosition):
+
+        Export ScrollingTreeFrameScrollingNodeIOS.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::visibleRectForLayerFlushing const):
+        (WebCore::RenderLayerCompositor::frameViewDidChangeSize):
+        (WebCore::RenderLayerCompositor::updateScrollLayerClipping):
+
+        If we don't have a separate clip layer, just resize and position the scroll layer.
+
+        (WebCore::RenderLayerCompositor::updateRootLayerPosition):
+        (WebCore::RenderLayerCompositor::updateOverflowControlsLayers):
+        (WebCore::RenderLayerCompositor::ensureRootLayer):
+
+        Use GraphicsLayer::Type::Scrolling as the scroll layer type when async frame scrolling is enabled.
+        Don't create a separate clip layer since the scroll layer will handle clipping.
+
+        * rendering/RenderLayerCompositor.h:
+
 2019-01-18  Ali Juma  <ajuma@chromium.org>
 
         FetchResponse::url should return the empty string for tainted responses
index a40886a..56a4790 100644 (file)
@@ -34,9 +34,9 @@ OBJC_CLASS CALayer;
 
 namespace WebCore {
 
-class ScrollingTreeFrameScrollingNodeIOS : public ScrollingTreeFrameScrollingNode {
+class WEBCORE_EXPORT ScrollingTreeFrameScrollingNodeIOS : public ScrollingTreeFrameScrollingNode {
 public:
-    WEBCORE_EXPORT static Ref<ScrollingTreeFrameScrollingNodeIOS> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
+    static Ref<ScrollingTreeFrameScrollingNodeIOS> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
     virtual ~ScrollingTreeFrameScrollingNodeIOS();
 
 protected:
@@ -55,14 +55,16 @@ protected:
     void updateLayersAfterDelegatedScroll(const FloatPoint&) override;
     void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) override;
 
+    void setScrollPosition(const FloatPoint&) override;
     void setScrollLayerPosition(const FloatPoint&, const FloatRect& layoutViewport) override;
 
     FloatPoint minimumScrollPosition() const override;
     FloatPoint maximumScrollPosition() const override;
 
+    CALayer *scrollLayer() const;
+
 private:
     void updateChildNodesAfterScroll(const FloatPoint&);
-    CALayer *scrollLayer() const { return m_scrollLayer.get(); }
 
     RetainPtr<CALayer> m_scrollLayer;
     RetainPtr<CALayer> m_counterScrollingLayer;
index 14f6ce7..24debd0 100644 (file)
@@ -104,6 +104,11 @@ FloatPoint ScrollingTreeFrameScrollingNodeIOS::scrollPosition() const
     return -m_scrollLayer.get().position;
 }
 
+void ScrollingTreeFrameScrollingNodeIOS::setScrollPosition(const FloatPoint& scrollPosition)
+{
+    ScrollingTreeFrameScrollingNode::setScrollPosition(scrollPosition);
+}
+
 void ScrollingTreeFrameScrollingNodeIOS::setScrollPositionWithoutContentEdgeConstraints(const FloatPoint& scrollPosition)
 {
     if (shouldUpdateScrollLayerPositionSynchronously()) {
@@ -210,6 +215,11 @@ FloatPoint ScrollingTreeFrameScrollingNodeIOS::maximumScrollPosition() const
     return position;
 }
 
+CALayer *ScrollingTreeFrameScrollingNodeIOS::scrollLayer() const
+{
+    return m_scrollLayer.get();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
index 2222d54..8a14a33 100644 (file)
@@ -447,8 +447,8 @@ FloatRect RenderLayerCompositor::visibleRectForLayerFlushing() const
 #if PLATFORM(IOS_FAMILY)
     return frameView.exposedContentRect();
 #else
-    // Having a m_clipLayer indicates that we're doing scrolling via GraphicsLayers.
-    FloatRect visibleRect = m_clipLayer ? FloatRect({ }, frameView.sizeForVisibleContent()) : frameView.visibleContentRect();
+    // Having a m_scrollLayer indicates that we're doing scrolling via GraphicsLayers.
+    FloatRect visibleRect = m_scrollLayer ? FloatRect({ }, frameView.sizeForVisibleContent()) : frameView.visibleContentRect();
 
     if (frameView.viewExposedRect())
         visibleRect.intersect(frameView.viewExposedRect().value());
@@ -1786,18 +1786,16 @@ void RenderLayerCompositor::frameViewDidChangeSize()
     if (auto* layer = m_renderView.layer())
         layer->setNeedsCompositingGeometryUpdate();
 
-    if (m_clipLayer) {
-        const FrameView& frameView = m_renderView.frameView();
-        m_clipLayer->setSize(frameView.sizeForVisibleContent());
-        m_clipLayer->setPosition(positionForClipLayer());
-
+    if (m_scrollLayer) {
+        updateScrollLayerClipping();
         frameViewDidScroll();
         updateOverflowControlsLayers();
 
 #if ENABLE(RUBBER_BANDING)
         if (m_layerForOverhangAreas) {
+            auto& frameView = m_renderView.frameView();
             m_layerForOverhangAreas->setSize(frameView.frameRect().size());
-            m_layerForOverhangAreas->setPosition(FloatPoint(0, m_renderView.frameView().topContentInset()));
+            m_layerForOverhangAreas->setPosition(FloatPoint(0, frameView.topContentInset()));
         }
 #endif
     }
@@ -1822,6 +1820,16 @@ void RenderLayerCompositor::updateScrollLayerPosition()
         fixedBackgroundLayer->setPosition(frameView.scrollPositionForFixedPosition());
 }
 
+void RenderLayerCompositor::updateScrollLayerClipping()
+{
+    auto* layerForClipping = this->layerForClipping();
+    if (!layerForClipping)
+        return;
+
+    layerForClipping->setSize(m_renderView.frameView().sizeForVisibleContent());
+    layerForClipping->setPosition(positionForClipLayer());
+}
+
 FloatPoint RenderLayerCompositor::positionForClipLayer() const
 {
     auto& frameView = m_renderView.frameView();
@@ -2051,10 +2059,8 @@ void RenderLayerCompositor::updateRootLayerPosition()
         m_rootContentLayer->setPosition(m_renderView.frameView().positionForRootContentLayer());
         m_rootContentLayer->setAnchorPoint(FloatPoint3D());
     }
-    if (m_clipLayer) {
-        m_clipLayer->setSize(m_renderView.frameView().sizeForVisibleContent());
-        m_clipLayer->setPosition(positionForClipLayer());
-    }
+
+    updateScrollLayerClipping();
 
 #if ENABLE(RUBBER_BANDING)
     if (m_contentShadowLayer && m_rootContentLayer) {
@@ -3287,7 +3293,7 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
 
             // We want the overhang areas layer to be positioned below the frame contents,
             // so insert it below the clip layer.
-            m_overflowControlsHostLayer->addChildBelow(*m_layerForOverhangAreas, m_clipLayer.get());
+            m_overflowControlsHostLayer->addChildBelow(*m_layerForOverhangAreas, layerForClipping());
         }
     } else
         GraphicsLayer::unparentAndClear(m_layerForOverhangAreas);
@@ -3399,23 +3405,30 @@ void RenderLayerCompositor::ensureRootLayer()
             m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
             m_overflowControlsHostLayer->setName("overflow controls host");
 
-            // Create a clipping layer if this is an iframe
-            m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
-            m_clipLayer->setName("frame clipping");
-            m_clipLayer->setMasksToBounds(true);
-            
-            m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
+            auto scrollLayerType = GraphicsLayer::Type::Normal;
+#if PLATFORM(IOS_FAMILY)
+            if (m_renderView.settings().asyncFrameScrollingEnabled())
+                scrollLayerType = GraphicsLayer::Type::Scrolling;
+#endif
+            m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), *this, scrollLayerType);
             m_scrollLayer->setName("frame scrolling");
 
-            // Hook them up
-            m_overflowControlsHostLayer->addChild(*m_clipLayer);
-            m_clipLayer->addChild(*m_scrollLayer);
-            m_scrollLayer->addChild(*m_rootContentLayer);
+            if (scrollLayerType == GraphicsLayer::Type::Scrolling) {
+                // Scroll layer clips so there is no need for a separate clipping layer.
+                m_overflowControlsHostLayer->addChild(*m_scrollLayer);
+            } else {
+                m_clipLayer = GraphicsLayer::create(graphicsLayerFactory(), *this);
+                m_clipLayer->setName("frame clipping");
+                m_clipLayer->setMasksToBounds(true);
+                m_clipLayer->setAnchorPoint(FloatPoint3D());
+
+                m_clipLayer->addChild(*m_scrollLayer);
+                m_overflowControlsHostLayer->addChild(*m_clipLayer);
+            }
 
-            m_clipLayer->setSize(m_renderView.frameView().sizeForVisibleContent());
-            m_clipLayer->setPosition(positionForClipLayer());
-            m_clipLayer->setAnchorPoint(FloatPoint3D());
+            m_scrollLayer->addChild(*m_rootContentLayer);
 
+            updateScrollLayerClipping();
             updateOverflowControlsLayers();
 
             if (hasCoordinatedScrolling())
index 051ff09..d73fe1b 100644 (file)
@@ -236,6 +236,7 @@ public:
     GraphicsLayer* clipLayer() const { return m_clipLayer.get(); }
     GraphicsLayer* rootContentLayer() const { return m_rootContentLayer.get(); }
 
+    GraphicsLayer* layerForClipping() const {  return m_clipLayer ? m_clipLayer.get() : m_scrollLayer.get();  }
 
 #if ENABLE(RUBBER_BANDING)
     GraphicsLayer* headerLayer() const { return m_layerForHeader.get(); }
@@ -432,6 +433,7 @@ private:
     void updateOverflowControlsLayers();
 
     void updateScrollLayerPosition();
+    void updateScrollLayerClipping();
 
     FloatPoint positionForClipLayer() const;
 
index 04862d5..9f789b9 100644 (file)
@@ -1,3 +1,31 @@
+2019-01-18  Antti Koivisto  <antti@apple.com>
+
+        Implement asynchronous frame scrolling for iOS
+        https://bugs.webkit.org/show_bug.cgi?id=193539
+        <rdar://problem/47379873>
+
+        Reviewed by Simon Fraser.
+
+        Add a scrolling node type that can handle UIScrollView backed frames.
+        It basically just instantiates and forwards to the existing ScrollingTreeScrollingNodeDelegateIOS.
+
+        * UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::createScrollingTreeNode):
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h: Added.
+        * UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm: Added.
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::create):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::ScrollingTreeFrameScrollingNodeRemoteIOS):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::~ScrollingTreeFrameScrollingNodeRemoteIOS):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateBeforeChildren):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterAncestorChange):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::scrollPosition const):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::setScrollLayerPosition):
+        (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterDelegatedScroll):
+        * WebKit.xcodeproj/project.pbxproj:
+
 2019-01-18  Chris Dumez  <cdumez@apple.com>
 
         Regression(PSON) Scroll position is not always restored properly when navigating back
index d2fa235..16e88f0 100644 (file)
@@ -454,6 +454,7 @@ UIProcess/RemoteLayerTree/mac/ScrollingTreeFrameScrollingNodeRemoteMac.cpp
 
 UIProcess/RemoteLayerTree/ios/RemoteLayerTreeHostIOS.mm
 UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm
+UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm
 UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
 UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm
 
index a7fcea8..62a386d 100644 (file)
@@ -34,6 +34,7 @@
 #include <WebCore/ScrollingTreeStickyNode.h>
 
 #if PLATFORM(IOS_FAMILY)
+#include "ScrollingTreeFrameScrollingNodeRemoteIOS.h"
 #include "ScrollingTreeOverflowScrollingNodeIOS.h"
 #include <WebCore/ScrollingTreeFrameScrollingNodeIOS.h>
 #else
@@ -115,7 +116,7 @@ Ref<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(ScrollingNod
     case ScrollingNodeType::MainFrame:
     case ScrollingNodeType::Subframe:
 #if PLATFORM(IOS_FAMILY)
-        return ScrollingTreeFrameScrollingNodeIOS::create(*this, nodeType, nodeID);
+        return ScrollingTreeFrameScrollingNodeRemoteIOS::create(*this, nodeType, nodeID);
 #else
         return ScrollingTreeFrameScrollingNodeRemoteMac::create(*this, nodeType, nodeID);
 #endif
index cd8ea33..9a45671 100644 (file)
@@ -68,6 +68,9 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
             if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::ScrollLayer))
                 scrollingStateNode.setLayer(layerTreeHost.layerForID(scrollingStateNode.layer()));
 
+            if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
+                scrollingStateNode.setScrolledContentsLayer(layerTreeHost.layerForID(scrollingStateNode.scrolledContentsLayer()));
+
             if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer))
                 scrollingStateNode.setCounterScrollingLayer(layerTreeHost.layerForID(scrollingStateNode.counterScrollingLayer()));
 
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.h
new file mode 100644 (file)
index 0000000..e4feb81
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
+
+#include <WebCore/ScrollingTreeFrameScrollingNodeIOS.h>
+
+namespace WebKit {
+
+class ScrollingTreeScrollingNodeDelegateIOS;
+
+class ScrollingTreeFrameScrollingNodeRemoteIOS : public WebCore::ScrollingTreeFrameScrollingNodeIOS {
+public:
+    static Ref<ScrollingTreeFrameScrollingNodeRemoteIOS> create(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
+    virtual ~ScrollingTreeFrameScrollingNodeRemoteIOS();
+
+private:
+    ScrollingTreeFrameScrollingNodeRemoteIOS(WebCore::ScrollingTree&, WebCore::ScrollingNodeType, WebCore::ScrollingNodeID);
+
+    void commitStateBeforeChildren(const WebCore::ScrollingStateNode&) override;
+    void commitStateAfterChildren(const WebCore::ScrollingStateNode&) override;
+
+    WebCore::FloatPoint scrollPosition() const override;
+    void setScrollLayerPosition(const WebCore::FloatPoint&, const WebCore::FloatRect& layoutViewport) override;
+
+    void updateLayersAfterDelegatedScroll(const WebCore::FloatPoint& scrollPosition) override;
+    void updateLayersAfterAncestorChange(const WebCore::ScrollingTreeNode& changedNode, const WebCore::FloatRect& fixedPositionRect, const WebCore::FloatSize& cumulativeDelta) override;
+
+    std::unique_ptr<ScrollingTreeScrollingNodeDelegateIOS> m_scrollingNodeDelegate;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(ASYNC_SCROLLING) && PLATFORM(IOS_FAMILY)
diff --git a/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm b/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm
new file mode 100644 (file)
index 0000000..b497b59
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ScrollingTreeFrameScrollingNodeRemoteIOS.h"
+
+#if PLATFORM(IOS_FAMILY) && ENABLE(ASYNC_SCROLLING)
+
+#import "ScrollingTreeScrollingNodeDelegateIOS.h"
+#import <WebCore/ScrollingStateScrollingNode.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+Ref<ScrollingTreeFrameScrollingNodeRemoteIOS> ScrollingTreeFrameScrollingNodeRemoteIOS::create(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
+{
+    return adoptRef(*new ScrollingTreeFrameScrollingNodeRemoteIOS(scrollingTree, nodeType, nodeID));
+}
+
+ScrollingTreeFrameScrollingNodeRemoteIOS::ScrollingTreeFrameScrollingNodeRemoteIOS(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
+    : ScrollingTreeFrameScrollingNodeIOS(scrollingTree, nodeType, nodeID)
+{
+}
+
+ScrollingTreeFrameScrollingNodeRemoteIOS::~ScrollingTreeFrameScrollingNodeRemoteIOS()
+{
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
+{
+    ScrollingTreeFrameScrollingNodeIOS::commitStateBeforeChildren(stateNode);
+
+    if (stateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollLayer)) {
+        if (scrollLayer() && [[scrollLayer() delegate] isKindOfClass:[UIScrollView self]])
+            m_scrollingNodeDelegate = std::make_unique<ScrollingTreeScrollingNodeDelegateIOS>(*this);
+        else
+            m_scrollingNodeDelegate = nullptr;
+    }
+
+    if (m_scrollingNodeDelegate)
+        m_scrollingNodeDelegate->commitStateBeforeChildren(downcast<ScrollingStateScrollingNode>(stateNode));
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren(const ScrollingStateNode& stateNode)
+{
+    ScrollingTreeFrameScrollingNodeIOS::commitStateAfterChildren(stateNode);
+
+    if (m_scrollingNodeDelegate)
+        m_scrollingNodeDelegate->commitStateAfterChildren(downcast<ScrollingStateScrollingNode>(stateNode));
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
+{
+    if (m_scrollingNodeDelegate) {
+        m_scrollingNodeDelegate->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
+        return;
+    }
+    ScrollingTreeFrameScrollingNodeIOS::updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
+}
+
+FloatPoint ScrollingTreeFrameScrollingNodeRemoteIOS::scrollPosition() const
+{
+    if (m_scrollingNodeDelegate)
+        return m_scrollingNodeDelegate->scrollPosition();
+
+    return ScrollingTreeFrameScrollingNodeIOS::scrollPosition();
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteIOS::setScrollLayerPosition(const FloatPoint& scrollPosition, const FloatRect& layoutViewport)
+{
+    if (m_scrollingNodeDelegate) {
+        m_scrollingNodeDelegate->setScrollLayerPosition(scrollPosition);
+        return;
+    }
+    ScrollingTreeFrameScrollingNodeIOS::setScrollLayerPosition(scrollPosition, layoutViewport);
+}
+
+void ScrollingTreeFrameScrollingNodeRemoteIOS::updateLayersAfterDelegatedScroll(const FloatPoint& scrollPosition)
+{
+    if (m_scrollingNodeDelegate) {
+        m_scrollingNodeDelegate->updateChildNodesAfterScroll(scrollPosition);
+        return;
+    }
+    ScrollingTreeFrameScrollingNodeIOS::updateLayersAfterDelegatedScroll(scrollPosition);
+}
+
+}
+
+#endif
index 4eb9b4a..020672e 100644 (file)
                E4436ECF1A0D040B00EAD204 /* NetworkCacheStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = E4436EC21A0CFDB200EAD204 /* NetworkCacheStorage.h */; };
                E489D28C1A0A2DB80078C06A /* NetworkCacheCoders.h in Headers */ = {isa = PBXBuildFile; fileRef = E489D2851A0A2DB80078C06A /* NetworkCacheCoders.h */; };
                E49D40D71AD3FB170066B7B9 /* NetworkCacheBlobStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = E49D40D61AD3FB170066B7B9 /* NetworkCacheBlobStorage.h */; };
+               E4D54D0421F1D72D007E3C36 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E40C1F9321F0B96E00530718 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h */; };
                E4E57F6B21A83B1200345F3C /* RemoteLayerTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E57F6A21A83B1100345F3C /* RemoteLayerTreeNode.h */; };
                E4E864931B16750700C82F40 /* VersionChecks.h in Headers */ = {isa = PBXBuildFile; fileRef = E4E8648E1B1673FB00C82F40 /* VersionChecks.h */; };
                E52CF55220A35C3A00DADA27 /* WebDataListSuggestionPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = E52CF55020A35C3A00DADA27 /* WebDataListSuggestionPicker.h */; };
                E404907321DE65F70037F0DB /* ScrollingTreeFrameScrollingNodeRemoteMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeFrameScrollingNodeRemoteMac.h; sourceTree = "<group>"; };
                E404907421DE65F70037F0DB /* ScrollerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollerMac.mm; sourceTree = "<group>"; };
                E404907521DE65F70037F0DB /* ScrollerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollerMac.h; sourceTree = "<group>"; };
+               E40C1F9321F0B96E00530718 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeFrameScrollingNodeRemoteIOS.h; sourceTree = "<group>"; };
+               E40C1F9521F0B97F00530718 /* ScrollingTreeFrameScrollingNodeRemoteIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingTreeFrameScrollingNodeRemoteIOS.mm; sourceTree = "<group>"; };
                E413F59B1AC1ADB600345360 /* NetworkCacheEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheEntry.h; sourceTree = "<group>"; };
                E413F59E1AC1AF9D00345360 /* NetworkCacheEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheEntry.cpp; sourceTree = "<group>"; };
                E42E060B1AA7440D00B11699 /* NetworkCacheIOChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheIOChannel.h; sourceTree = "<group>"; };
                                2DC18FB1218A6E9E0025A88D /* RemoteLayerTreeViews.h */,
                                2DC18FB2218A6E9E0025A88D /* RemoteLayerTreeViews.mm */,
                                0F0C365B18C05CA100F607D7 /* RemoteScrollingCoordinatorProxyIOS.mm */,
+                               E40C1F9321F0B96E00530718 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h */,
+                               E40C1F9521F0B97F00530718 /* ScrollingTreeFrameScrollingNodeRemoteIOS.mm */,
                                0F931C1A18C5711900DBA7C3 /* ScrollingTreeOverflowScrollingNodeIOS.h */,
                                0F931C1B18C5711900DBA7C3 /* ScrollingTreeOverflowScrollingNodeIOS.mm */,
                                0F931C1A18C5711900DBB8D4 /* ScrollingTreeScrollingNodeDelegateIOS.h */,
                                1A81B38118BD66AD0007FDAC /* _WKVisitedLinkStore.h in Headers */,
                                1A81B38518BD673A0007FDAC /* _WKVisitedLinkStoreInternal.h in Headers */,
                                1AE286781C7E76510069AC4F /* _WKWebsiteDataSize.h in Headers */,
+                               E4D54D0421F1D72D007E3C36 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h in Headers */,
                                1AE286801C7F92C00069AC4F /* _WKWebsiteDataSizeInternal.h in Headers */,
                                1AFB4C721ADF155D00B33339 /* _WKWebsiteDataStore.h in Headers */,
                                5120C8351E5B74B90025B250 /* _WKWebsiteDataStoreConfiguration.h in Headers */,