Source/WebCore:
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2019 16:10:43 +0000 (16:10 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Jan 2019 16:10:43 +0000 (16:10 +0000)
Add "frame hosting" nodes to the scrolling tree
https://bugs.webkit.org/show_bug.cgi?id=193753

Reviewed by Antti Koivisto.

When the scrolling tree crosses frame boundaries, mutations in the parent frame currently
require the iframe's scrolling node to get reparented in a new ancestor, which requires
a layer tree walk of the parent frame. This is error-prone, and not very future-proof.

Fix this by introducing "frame hosting" scrolling tree nodes. These are mostly inert
nodes that are owned by the RenderIFrame's layer backing in the parent frame, and exist
to provide a consistent parent node for the subframe's scrolling node.

This patch adds the node types, but does not instantiate them yet.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::operator<<):
* page/scrolling/ScrollingCoordinator.h:
* page/scrolling/ScrollingStateFrameHostingNode.cpp: Added.
(WebCore::ScrollingStateFrameHostingNode::create):
(WebCore::ScrollingStateFrameHostingNode::ScrollingStateFrameHostingNode):
(WebCore::ScrollingStateFrameHostingNode::clone):
(WebCore::ScrollingStateFrameHostingNode::dumpProperties const):
* page/scrolling/ScrollingStateFrameHostingNode.h: Added.
* page/scrolling/ScrollingStateNode.h:
(WebCore::ScrollingStateNode::isFrameHostingNode const):
* page/scrolling/ScrollingStateTree.cpp:
(WebCore::ScrollingStateTree::createNode):
* page/scrolling/ScrollingTreeFrameHostingNode.cpp: Added.
(WebCore::ScrollingTreeFrameHostingNode::create):
(WebCore::ScrollingTreeFrameHostingNode::ScrollingTreeFrameHostingNode):
(WebCore::ScrollingTreeFrameHostingNode::commitStateBeforeChildren):
(WebCore::ScrollingTreeFrameHostingNode::updateLayersAfterAncestorChange):
(WebCore::ScrollingTreeFrameHostingNode::dumpProperties const):
* page/scrolling/ScrollingTreeFrameHostingNode.h: Added.
* page/scrolling/ScrollingTreeNode.h:
(WebCore::ScrollingTreeNode::isFrameHostingNode const):
* page/scrolling/ios/ScrollingTreeIOS.cpp:
(WebCore::ScrollingTreeIOS::createScrollingTreeNode):
* page/scrolling/mac/ScrollingTreeMac.cpp:
(ScrollingTreeMac::createScrollingTreeNode):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::~RenderLayerBacking):
(WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
(WebCore::operator<<):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::scrollCoordinationRoleForNodeType):
(WebCore::RenderLayerCompositor::detachScrollCoordinatedLayerWithRole):
(WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
(WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
* rendering/RenderLayerCompositor.h:

Source/WebKit:
Create "frame hosting" nodes for the scrolling tree
https://bugs.webkit.org/show_bug.cgi?id=193753

Reviewed by Antti Koivisto.

When the scrolling tree crosses frame boundaries, mutations in the parent frame currently
require the iframe's scrolling node to get reparented in a new ancestor, which requires
a layer tree walk of the parent frame. This is error-prone, and not very future-proof.

Fix this by introducing "frame hosting" scrolling tree nodes. These are mostly inert
nodes that are owned by the RenderIFrame's layer backing in the parent frame, and exist
to provide a consistent parent node for the subframe's scrolling node.

This patch adds the node types, but does not instantiate them yet.

* Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<ScrollingStateFrameHostingNode>::encode):
(ArgumentCoder<ScrollingStateFrameHostingNode>::decode):
(WebKit::encodeNodeAndDescendants):
(WebKit::RemoteScrollingCoordinatorTransaction::decode):
(WebKit::dump):
* UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
(WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
* UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
(WebKit::RemoteScrollingTree::createScrollingTreeNode):
* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):

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

23 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.cpp [new file with mode: 0644]
Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.h [new file with mode: 0644]
Source/WebCore/page/scrolling/ScrollingStateNode.h
Source/WebCore/page/scrolling/ScrollingStateTree.cpp
Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp [new file with mode: 0644]
Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h [new file with mode: 0644]
Source/WebCore/page/scrolling/ScrollingTreeNode.h
Source/WebCore/page/scrolling/ios/ScrollingTreeIOS.cpp
Source/WebCore/page/scrolling/mac/ScrollingTreeMac.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm

index afdb6af..169def5 100644 (file)
@@ -1,3 +1,60 @@
+2019-01-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Add "frame hosting" nodes to the scrolling tree
+        https://bugs.webkit.org/show_bug.cgi?id=193753
+
+        Reviewed by Antti Koivisto.
+
+        When the scrolling tree crosses frame boundaries, mutations in the parent frame currently
+        require the iframe's scrolling node to get reparented in a new ancestor, which requires
+        a layer tree walk of the parent frame. This is error-prone, and not very future-proof.
+
+        Fix this by introducing "frame hosting" scrolling tree nodes. These are mostly inert
+        nodes that are owned by the RenderIFrame's layer backing in the parent frame, and exist
+        to provide a consistent parent node for the subframe's scrolling node.
+
+        This patch adds the node types, but does not instantiate them yet.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/scrolling/ScrollingCoordinator.cpp:
+        (WebCore::operator<<):
+        * page/scrolling/ScrollingCoordinator.h:
+        * page/scrolling/ScrollingStateFrameHostingNode.cpp: Added.
+        (WebCore::ScrollingStateFrameHostingNode::create):
+        (WebCore::ScrollingStateFrameHostingNode::ScrollingStateFrameHostingNode):
+        (WebCore::ScrollingStateFrameHostingNode::clone):
+        (WebCore::ScrollingStateFrameHostingNode::dumpProperties const):
+        * page/scrolling/ScrollingStateFrameHostingNode.h: Added.
+        * page/scrolling/ScrollingStateNode.h:
+        (WebCore::ScrollingStateNode::isFrameHostingNode const):
+        * page/scrolling/ScrollingStateTree.cpp:
+        (WebCore::ScrollingStateTree::createNode):
+        * page/scrolling/ScrollingTreeFrameHostingNode.cpp: Added.
+        (WebCore::ScrollingTreeFrameHostingNode::create):
+        (WebCore::ScrollingTreeFrameHostingNode::ScrollingTreeFrameHostingNode):
+        (WebCore::ScrollingTreeFrameHostingNode::commitStateBeforeChildren):
+        (WebCore::ScrollingTreeFrameHostingNode::updateLayersAfterAncestorChange):
+        (WebCore::ScrollingTreeFrameHostingNode::dumpProperties const):
+        * page/scrolling/ScrollingTreeFrameHostingNode.h: Added.
+        * page/scrolling/ScrollingTreeNode.h:
+        (WebCore::ScrollingTreeNode::isFrameHostingNode const):
+        * page/scrolling/ios/ScrollingTreeIOS.cpp:
+        (WebCore::ScrollingTreeIOS::createScrollingTreeNode):
+        * page/scrolling/mac/ScrollingTreeMac.cpp:
+        (ScrollingTreeMac::createScrollingTreeNode):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::~RenderLayerBacking):
+        (WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
+        (WebCore::operator<<):
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::scrollCoordinationRoleForNodeType):
+        (WebCore::RenderLayerCompositor::detachScrollCoordinatedLayerWithRole):
+        (WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
+        (WebCore::RenderLayerCompositor::updateScrollCoordinatedLayer):
+        * rendering/RenderLayerCompositor.h:
+
 2019-01-24  Eric Carlson  <eric.carlson@apple.com>
 
         [iOS] Enable media element volume on iPad
index d2adb0e..b26d75a 100644 (file)
@@ -1575,6 +1575,7 @@ page/scrolling/ScrollLatchingState.cpp
 page/scrolling/ScrollingConstraints.cpp
 page/scrolling/ScrollingCoordinator.cpp
 page/scrolling/ScrollingStateFixedNode.cpp
+page/scrolling/ScrollingStateFrameHostingNode.cpp
 page/scrolling/ScrollingStateFrameScrollingNode.cpp
 page/scrolling/ScrollingStateNode.cpp
 page/scrolling/ScrollingStateOverflowScrollingNode.cpp
@@ -1583,6 +1584,7 @@ page/scrolling/ScrollingStateStickyNode.cpp
 page/scrolling/ScrollingStateTree.cpp
 page/scrolling/ScrollingThread.cpp
 page/scrolling/ScrollingTree.cpp
+page/scrolling/ScrollingTreeFrameHostingNode.cpp
 page/scrolling/ScrollingTreeFrameScrollingNode.cpp
 page/scrolling/ScrollingTreeNode.cpp
 page/scrolling/ScrollingTreeOverflowScrollingNode.cpp
index dab4df5..10c2595 100644 (file)
                0FCF332F0F2B9A25004B6795 /* WebLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCF332B0F2B9A25004B6795 /* WebLayer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD3080F117CF7E700A791F7 /* RenderFrameBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD3080D117CF7E700A791F7 /* RenderFrameBase.h */; };
                0FD308D6117D168500A791F7 /* RenderIFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD308D4117D168400A791F7 /* RenderIFrame.h */; };
+               0FD41E6821F80C0E000C006D /* ScrollingTreeFrameHostingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD41E6621F80282000C006D /* ScrollingTreeFrameHostingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FD41E6921F80D14000C006D /* ScrollingStateFrameHostingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD41E6521F80261000C006D /* ScrollingStateFrameHostingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FD723820EC8BD9300CA5DD7 /* FloatQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FDA7C17188322EB00C954B5 /* JSTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDA7C11188322EB00C954B5 /* JSTouch.h */; };
                0FDA7C19188322EB00C954B5 /* JSTouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDA7C13188322EB00C954B5 /* JSTouchEvent.h */; };
                0FD3080D117CF7E700A791F7 /* RenderFrameBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFrameBase.h; sourceTree = "<group>"; };
                0FD308D3117D168400A791F7 /* RenderIFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderIFrame.cpp; sourceTree = "<group>"; };
                0FD308D4117D168400A791F7 /* RenderIFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderIFrame.h; sourceTree = "<group>"; };
+               0FD41E6321F80260000C006D /* ScrollingStateFrameHostingNode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingStateFrameHostingNode.cpp; sourceTree = "<group>"; };
+               0FD41E6521F80261000C006D /* ScrollingStateFrameHostingNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingStateFrameHostingNode.h; sourceTree = "<group>"; };
+               0FD41E6621F80282000C006D /* ScrollingTreeFrameHostingNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeFrameHostingNode.h; sourceTree = "<group>"; };
+               0FD41E6721F80282000C006D /* ScrollingTreeFrameHostingNode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeFrameHostingNode.cpp; sourceTree = "<group>"; };
                0FD723800EC8BD9300CA5DD7 /* FloatQuad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatQuad.h; sourceTree = "<group>"; };
                0FD723810EC8BD9300CA5DD7 /* FloatQuad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FloatQuad.cpp; sourceTree = "<group>"; };
                0FDA7C10188322EB00C954B5 /* JSTouch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTouch.cpp; sourceTree = "<group>"; };
                                51C61B091DE536E7008A212D /* ScrollingMomentumCalculator.h */,
                                93C38BFC164473C700091EB2 /* ScrollingStateFixedNode.cpp */,
                                93C38BFD164473C700091EB2 /* ScrollingStateFixedNode.h */,
+                               0FD41E6321F80260000C006D /* ScrollingStateFrameHostingNode.cpp */,
+                               0FD41E6521F80261000C006D /* ScrollingStateFrameHostingNode.h */,
                                0FEA3E7A191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.cpp */,
                                0FEA3E79191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h */,
                                931CBD06161A44E900E4C874 /* ScrollingStateNode.cpp */,
                                1AF62F2114DAFE790041556C /* ScrollingThread.h */,
                                1AAADDA114DB409F00AF64B3 /* ScrollingTree.cpp */,
                                1AAADDA214DB409F00AF64B3 /* ScrollingTree.h */,
+                               0FD41E6721F80282000C006D /* ScrollingTreeFrameHostingNode.cpp */,
+                               0FD41E6621F80282000C006D /* ScrollingTreeFrameHostingNode.h */,
                                0FEA3E85191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.cpp */,
                                0FEA3E86191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h */,
                                1AAADDE114DC8C8F00AF64B3 /* ScrollingTreeNode.cpp */,
                                51C61B0B1DE536E7008A212D /* ScrollingMomentumCalculator.h in Headers */,
                                517DEEE81DE94B0800B91644 /* ScrollingMomentumCalculatorMac.h in Headers */,
                                93C38BFF164473C700091EB2 /* ScrollingStateFixedNode.h in Headers */,
+                               0FD41E6921F80D14000C006D /* ScrollingStateFrameHostingNode.h in Headers */,
                                0FEA3E7B191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h in Headers */,
                                931CBD0D161A44E900E4C874 /* ScrollingStateNode.h in Headers */,
                                0FEA3E84191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h in Headers */,
                                1AF62F2614DAFEA10041556C /* ScrollingThread.h in Headers */,
                                1AAADDA414DB409F00AF64B3 /* ScrollingTree.h in Headers */,
                                93C38C03164473DD00091EB2 /* ScrollingTreeFixedNode.h in Headers */,
+                               0FD41E6821F80C0E000C006D /* ScrollingTreeFrameHostingNode.h in Headers */,
                                0FEA3E88191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h in Headers */,
                                0FC4E411187F82E10045882C /* ScrollingTreeFrameScrollingNodeIOS.h in Headers */,
                                93C4A4151629DF5A00C3EB6E /* ScrollingTreeFrameScrollingNodeMac.h in Headers */,
index 908c221..c4faedd 100644 (file)
@@ -431,6 +431,9 @@ TextStream& operator<<(TextStream& ts, ScrollingNodeType nodeType)
     case ScrollingNodeType::Subframe:
         ts << "subframe-scrolling";
         break;
+    case ScrollingNodeType::FrameHosting:
+        ts << "frame-hosting";
+        break;
     case ScrollingNodeType::Overflow:
         ts << "overflow-scrolling";
         break;
index f7a1c56..ac976e3 100644 (file)
@@ -57,6 +57,7 @@ typedef uint64_t ScrollingNodeID;
 enum class ScrollingNodeType : uint8_t {
     MainFrame,
     Subframe,
+    FrameHosting,
     Overflow,
     Fixed,
     Sticky
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.cpp b/Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.cpp
new file mode 100644 (file)
index 0000000..0cebd30
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "ScrollingStateFrameHostingNode.h"
+
+#if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
+
+#include "ScrollingStateTree.h"
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+
+Ref<ScrollingStateFrameHostingNode> ScrollingStateFrameHostingNode::create(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
+{
+    return adoptRef(*new ScrollingStateFrameHostingNode(stateTree, nodeID));
+}
+
+ScrollingStateFrameHostingNode::ScrollingStateFrameHostingNode(ScrollingStateTree& stateTree, ScrollingNodeID nodeID)
+    : ScrollingStateNode(ScrollingNodeType::FrameHosting, stateTree, nodeID)
+{
+    ASSERT(isFrameHostingNode());
+}
+
+ScrollingStateFrameHostingNode::ScrollingStateFrameHostingNode(const ScrollingStateFrameHostingNode& stateNode, ScrollingStateTree& adoptiveTree)
+    : ScrollingStateNode(stateNode, adoptiveTree)
+{
+}
+
+ScrollingStateFrameHostingNode::~ScrollingStateFrameHostingNode() = default;
+
+Ref<ScrollingStateNode> ScrollingStateFrameHostingNode::clone(ScrollingStateTree& adoptiveTree)
+{
+    return adoptRef(*new ScrollingStateFrameHostingNode(*this, adoptiveTree));
+}
+
+void ScrollingStateFrameHostingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
+{
+    ts << "Frame hosting node";
+    ScrollingStateNode::dumpProperties(ts, behavior);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
diff --git a/Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.h b/Source/WebCore/page/scrolling/ScrollingStateFrameHostingNode.h
new file mode 100644 (file)
index 0000000..1afe3e6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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) || USE(COORDINATED_GRAPHICS)
+
+#include "ScrollingStateFrameHostingNode.h"
+
+namespace WebCore {
+
+class Scrollbar;
+
+class ScrollingStateFrameHostingNode final : public ScrollingStateNode {
+public:
+    WEBCORE_EXPORT static Ref<ScrollingStateFrameHostingNode> create(ScrollingStateTree&, ScrollingNodeID);
+    Ref<ScrollingStateNode> clone(ScrollingStateTree&) override;
+
+    virtual ~ScrollingStateFrameHostingNode();
+
+    void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
+
+private:
+    ScrollingStateFrameHostingNode(ScrollingStateTree&, ScrollingNodeID);
+    ScrollingStateFrameHostingNode(const ScrollingStateFrameHostingNode&, ScrollingStateTree&);
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ScrollingStateFrameHostingNode, isFrameHostingNode())
+
+#endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
index a5a265c..c28872f 100644 (file)
@@ -200,6 +200,7 @@ public:
     bool isStickyNode() const { return m_nodeType == ScrollingNodeType::Sticky; }
     bool isScrollingNode() const { return isFrameScrollingNode() || isOverflowScrollingNode(); }
     bool isFrameScrollingNode() const { return m_nodeType == ScrollingNodeType::MainFrame || m_nodeType == ScrollingNodeType::Subframe; }
+    bool isFrameHostingNode() const { return m_nodeType == ScrollingNodeType::FrameHosting; }
     bool isOverflowScrollingNode() const { return m_nodeType == ScrollingNodeType::Overflow; }
 
     virtual Ref<ScrollingStateNode> clone(ScrollingStateTree& adoptiveTree) = 0;
index b2bd266..b1a26b9 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "AsyncScrollingCoordinator.h"
 #include "ScrollingStateFixedNode.h"
+#include "ScrollingStateFrameHostingNode.h"
 #include "ScrollingStateFrameScrollingNode.h"
 #include "ScrollingStateOverflowScrollingNode.h"
 #include "ScrollingStateStickyNode.h"
@@ -71,6 +72,8 @@ Ref<ScrollingStateNode> ScrollingStateTree::createNode(ScrollingNodeType nodeTyp
     case ScrollingNodeType::MainFrame:
     case ScrollingNodeType::Subframe:
         return ScrollingStateFrameScrollingNode::create(*this, nodeType, nodeID);
+    case ScrollingNodeType::FrameHosting:
+        return ScrollingStateFrameHostingNode::create(*this, nodeID);
     case ScrollingNodeType::Overflow:
         return ScrollingStateOverflowScrollingNode::create(*this, nodeID);
     case ScrollingNodeType::Fixed:
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp
new file mode 100644 (file)
index 0000000..34718e5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "ScrollingTreeFrameHostingNode.h"
+
+#if ENABLE(ASYNC_SCROLLING)
+
+#include "Logging.h"
+#include "ScrollingStateTree.h"
+#include "ScrollingTree.h"
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+
+Ref<ScrollingTreeFrameHostingNode> ScrollingTreeFrameHostingNode::create(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
+{
+    return adoptRef(*new ScrollingTreeFrameHostingNode(scrollingTree, nodeID));
+}
+
+ScrollingTreeFrameHostingNode::ScrollingTreeFrameHostingNode(ScrollingTree& scrollingTree, ScrollingNodeID nodeID)
+    : ScrollingTreeNode(scrollingTree, ScrollingNodeType::FrameHosting, nodeID)
+{
+    ASSERT(isFrameHostingNode());
+}
+
+ScrollingTreeFrameHostingNode::~ScrollingTreeFrameHostingNode() = default;
+
+void ScrollingTreeFrameHostingNode::commitStateBeforeChildren(const ScrollingStateNode&)
+{
+    // Nothing to do.
+}
+
+void ScrollingTreeFrameHostingNode::updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta)
+{
+    if (!m_children)
+        return;
+
+    for (auto& child : *m_children)
+        child->updateLayersAfterAncestorChange(changedNode, fixedPositionRect, cumulativeDelta);
+}
+
+void ScrollingTreeFrameHostingNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const
+{
+    ts << "frame hosting node";
+    ScrollingTreeNode::dumpProperties(ts, behavior);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h b/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h
new file mode 100644 (file)
index 0000000..fac8b5c
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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)
+
+#include "ScrollingTreeNode.h"
+
+namespace WebCore {
+
+class ScrollingTree;
+
+class ScrollingTreeFrameHostingNode : public ScrollingTreeNode {
+public:
+    WEBCORE_EXPORT static Ref<ScrollingTreeFrameHostingNode> create(ScrollingTree&, ScrollingNodeID);
+    virtual ~ScrollingTreeFrameHostingNode();
+
+private:
+    ScrollingTreeFrameHostingNode(ScrollingTree&, ScrollingNodeID);
+
+    void commitStateBeforeChildren(const ScrollingStateNode&) final;
+    void updateLayersAfterAncestorChange(const ScrollingTreeNode& changedNode, const FloatRect& fixedPositionRect, const FloatSize& cumulativeDelta) final;
+
+    WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeFrameHostingNode, isFrameHostingNode())
+
+#endif // ENABLE(ASYNC_SCROLLING)
index bf7f61a..2f4415a 100644 (file)
@@ -51,6 +51,7 @@ public:
     bool isStickyNode() const { return nodeType() == ScrollingNodeType::Sticky; }
     bool isScrollingNode() const { return isFrameScrollingNode() || isOverflowScrollingNode(); }
     bool isFrameScrollingNode() const { return nodeType() == ScrollingNodeType::MainFrame || nodeType() == ScrollingNodeType::Subframe; }
+    bool isFrameHostingNode() const { return nodeType() == ScrollingNodeType::FrameHosting; }
     bool isOverflowScrollingNode() const { return nodeType() == ScrollingNodeType::Overflow; }
 
     virtual void commitStateBeforeChildren(const ScrollingStateNode&) = 0;
index 90861ae..ac9e861 100644 (file)
@@ -32,6 +32,7 @@
 #include "PlatformWheelEvent.h"
 #include "ScrollingThread.h"
 #include "ScrollingTreeFixedNode.h"
+#include "ScrollingTreeFrameHostingNode.h"
 #include "ScrollingTreeFrameScrollingNodeIOS.h"
 #include "ScrollingTreeNode.h"
 #include "ScrollingTreeScrollingNode.h"
@@ -89,6 +90,8 @@ Ref<ScrollingTreeNode> ScrollingTreeIOS::createScrollingTreeNode(ScrollingNodeTy
     case ScrollingNodeType::MainFrame:
     case ScrollingNodeType::Subframe:
         return ScrollingTreeFrameScrollingNodeIOS::create(*this, nodeType, nodeID);
+    case ScrollingNodeType::FrameHosting:
+        return ScrollingTreeFrameHostingNode::create(*this, nodeID);
     case ScrollingNodeType::Overflow:
         ASSERT_NOT_REACHED();
         break;
index 6010e3a..b6ca948 100644 (file)
@@ -27,6 +27,7 @@
 #include "ScrollingTreeMac.h"
 
 #include "ScrollingTreeFixedNode.h"
+#include "ScrollingTreeFrameHostingNode.h"
 #include "ScrollingTreeFrameScrollingNodeMac.h"
 #include "ScrollingTreeOverflowScrollingNodeMac.h"
 #include "ScrollingTreeStickyNode.h"
@@ -51,6 +52,8 @@ Ref<ScrollingTreeNode> ScrollingTreeMac::createScrollingTreeNode(ScrollingNodeTy
     case ScrollingNodeType::MainFrame:
     case ScrollingNodeType::Subframe:
         return ScrollingTreeFrameScrollingNodeMac::create(*this, nodeType, nodeID);
+    case ScrollingNodeType::FrameHosting:
+        return ScrollingTreeFrameHostingNode::create(*this, nodeID);
     case ScrollingNodeType::Overflow:
         return ScrollingTreeOverflowScrollingNodeMac::create(*this, nodeID);
         break;
index 18ddc67..dacaa3d 100644 (file)
@@ -244,7 +244,7 @@ RenderLayerBacking::~RenderLayerBacking()
     updateBackgroundLayer(false);
     updateMaskingLayer(false, false);
     updateScrollingLayers(false);
-    detachFromScrollingCoordinator({ ScrollCoordinationRole::Scrolling, ScrollCoordinationRole::ViewportConstrained });
+    detachFromScrollingCoordinator({ ScrollCoordinationRole::Scrolling, ScrollCoordinationRole::ViewportConstrained, ScrollCoordinationRole::FrameHosting });
     destroyGraphicsLayers();
 }
 
@@ -1776,13 +1776,19 @@ void RenderLayerBacking::detachFromScrollingCoordinator(OptionSet<ScrollCoordina
     if (!scrollingCoordinator)
         return;
 
-    if ((roles.contains(ScrollCoordinationRole::Scrolling)) && m_scrollingNodeID) {
+    if (roles.contains(ScrollCoordinationRole::Scrolling) && m_scrollingNodeID) {
         LOG(Compositing, "Detaching Scrolling node %" PRIu64, m_scrollingNodeID);
         scrollingCoordinator->detachFromStateTree(m_scrollingNodeID);
         m_scrollingNodeID = 0;
     }
-    
-    if ((roles.contains(ScrollCoordinationRole::ViewportConstrained)) && m_viewportConstrainedNodeID) {
+
+    if (roles.contains(ScrollCoordinationRole::Scrolling) && m_frameHostingNodeID) {
+        LOG(Compositing, "Detaching FrameHosting node %" PRIu64, m_frameHostingNodeID);
+        scrollingCoordinator->detachFromStateTree(m_frameHostingNodeID);
+        m_frameHostingNodeID = 0;
+    }
+
+    if (roles.contains(ScrollCoordinationRole::ViewportConstrained) && m_viewportConstrainedNodeID) {
         LOG(Compositing, "Detaching ViewportConstrained node %" PRIu64, m_viewportConstrainedNodeID);
         scrollingCoordinator->detachFromStateTree(m_viewportConstrainedNodeID);
         m_viewportConstrainedNodeID = 0;
@@ -3081,6 +3087,8 @@ TextStream& operator<<(TextStream& ts, const RenderLayerBacking& backing)
         ts << " viewport constrained scrolling node " << nodeID;
     if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling))
         ts << " scrolling node " << nodeID;
+    if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::FrameHosting))
+        ts << " frame hosting node " << nodeID;
     return ts;
 }
 
index 4b0301d..f7c89d6 100644 (file)
@@ -112,6 +112,8 @@ public:
         switch (role) {
         case ScrollCoordinationRole::Scrolling:
             return m_scrollingNodeID;
+        case ScrollCoordinationRole::FrameHosting:
+            return m_frameHostingNodeID;
         case ScrollCoordinationRole::ViewportConstrained:
             return m_viewportConstrainedNodeID;
         }
@@ -124,6 +126,9 @@ public:
         case ScrollCoordinationRole::Scrolling:
             m_scrollingNodeID = nodeID;
             break;
+        case ScrollCoordinationRole::FrameHosting:
+            m_frameHostingNodeID = nodeID;
+            break;
         case ScrollCoordinationRole::ViewportConstrained:
             m_viewportConstrainedNodeID = nodeID;
             setIsScrollCoordinatedWithViewportConstrainedRole(nodeID);
@@ -131,7 +136,10 @@ public:
         }
     }
     
-    ScrollingNodeID scrollingNodeIDForChildren() const { return m_scrollingNodeID ? m_scrollingNodeID : m_viewportConstrainedNodeID; }
+    ScrollingNodeID scrollingNodeIDForChildren() const
+    {
+        return m_frameHostingNodeID ? m_frameHostingNodeID : (m_scrollingNodeID ? m_scrollingNodeID : m_viewportConstrainedNodeID);
+    }
 
     void setIsScrollCoordinatedWithViewportConstrainedRole(bool);
 
@@ -378,6 +386,7 @@ private:
 
     ScrollingNodeID m_viewportConstrainedNodeID { 0 };
     ScrollingNodeID m_scrollingNodeID { 0 };
+    ScrollingNodeID m_frameHostingNodeID { 0 };
 
     bool m_artificiallyInflatedBounds { false }; // bounds had to be made non-zero to make transform-origin work
     bool m_isMainFrameRenderViewLayer { false };
index 12949e6..2e50790 100644 (file)
@@ -3799,6 +3799,8 @@ static inline ScrollCoordinationRole scrollCoordinationRoleForNodeType(Scrolling
     case ScrollingNodeType::Subframe:
     case ScrollingNodeType::Overflow:
         return ScrollCoordinationRole::Scrolling;
+    case ScrollingNodeType::FrameHosting:
+        return ScrollCoordinationRole::FrameHosting;
     case ScrollingNodeType::Fixed:
     case ScrollingNodeType::Sticky:
         return ScrollCoordinationRole::ViewportConstrained;
@@ -3831,6 +3833,22 @@ ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, S
     return nodeID;
 }
 
+void RenderLayerCompositor::detachScrollCoordinatedLayerWithRole(RenderLayer& layer, ScrollingCoordinator& scrollingCoordinator, ScrollCoordinationRole role)
+{
+    auto nodeID = layer.backing()->scrollingNodeIDForRole(role);
+    if (!nodeID)
+        return;
+
+    auto childNodes = scrollingCoordinator.childrenOfNode(nodeID);
+    for (auto childNodeID : childNodes) {
+        // FIXME: The child might be in a child frame. Need to do something that crosses frame boundaries.
+        if (auto* layer = m_scrollingNodeToLayerMap.get(childNodeID))
+            layer->setNeedsScrollingTreeUpdate();
+    }
+
+    m_scrollingNodeToLayerMap.remove(nodeID);
+}
+
 void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, OptionSet<ScrollCoordinationRole> roles)
 {
     auto* backing = layer.backing();
@@ -3839,28 +3857,14 @@ void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, Opt
 
     auto* scrollingCoordinator = this->scrollingCoordinator();
 
-    auto dirtyDescendantScrollingLayers = [&] (ScrollingNodeID nodeID) {
-        auto childNodes = scrollingCoordinator->childrenOfNode(nodeID);
-        for (auto childNodeID : childNodes) {
-            // FIXME: The child might be in a child frame. Need to do something that crosses frame boundaries.
-            if (auto* layer = m_scrollingNodeToLayerMap.get(childNodeID))
-                layer->setNeedsScrollingTreeUpdate();
-        }
-    };
+    if (roles.contains(ScrollCoordinationRole::Scrolling))
+        detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::Scrolling);
 
-    if (roles.contains(ScrollCoordinationRole::Scrolling)) {
-        if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling)) {
-            dirtyDescendantScrollingLayers(nodeID);
-            m_scrollingNodeToLayerMap.remove(nodeID);
-        }
-    }
+    if (roles.contains(ScrollCoordinationRole::FrameHosting))
+        detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::FrameHosting);
 
-    if (roles.contains(ScrollCoordinationRole::ViewportConstrained)) {
-        if (ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(ScrollCoordinationRole::ViewportConstrained)) {
-            dirtyDescendantScrollingLayers(nodeID);
-            m_scrollingNodeToLayerMap.remove(nodeID);
-        }
-    }
+    if (roles.contains(ScrollCoordinationRole::ViewportConstrained))
+        detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::ViewportConstrained);
 
     backing->detachFromScrollingCoordinator(roles);
 }
@@ -3948,6 +3952,7 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt
                 break;
             case ScrollingNodeType::MainFrame:
             case ScrollingNodeType::Subframe:
+            case ScrollingNodeType::FrameHosting:
             case ScrollingNodeType::Overflow:
                 break;
             }
@@ -3997,6 +4002,18 @@ void RenderLayerCompositor::updateScrollCoordinatedLayer(RenderLayer& layer, Opt
         }
     } else
         detachScrollCoordinatedLayer(layer, ScrollCoordinationRole::Scrolling);
+
+    if (roles.contains(ScrollCoordinationRole::FrameHosting)) {
+        ScrollingNodeID nodeID = attachScrollingNode(layer, ScrollingNodeType::FrameHosting, parentNodeID);
+        if (!nodeID)
+            return;
+
+        if (changes & ScrollingNodeChangeFlags::Layer)
+            scrollingCoordinator->setNodeLayers(nodeID, backing->graphicsLayer());
+
+        LOG(Compositing, "Registering Scrolling scrolling node %" PRIu64 " (layer %" PRIu64 ") as child of %" PRIu64, nodeID, backing->graphicsLayer()->primaryLayerID(), parentNodeID);
+    } else
+        detachScrollCoordinatedLayer(layer, ScrollCoordinationRole::FrameHosting);
 }
 
 ScrollableArea* RenderLayerCompositor::scrollableAreaForScrollLayerID(ScrollingNodeID nodeID) const
index 783fed7..c33f993 100644 (file)
@@ -85,7 +85,8 @@ enum class CompositingReason {
 
 enum class ScrollCoordinationRole {
     ViewportConstrained = 1 << 0,
-    Scrolling           = 1 << 1
+    Scrolling           = 1 << 1,
+    FrameHosting        = 1 << 2,
 };
 
 #if PLATFORM(IOS_FAMILY)
@@ -479,6 +480,7 @@ private:
     ScrollingNodeID attachScrollingNode(RenderLayer&, ScrollingNodeType, ScrollingNodeID parentNodeID);
     void updateScrollCoordinatedLayer(RenderLayer&, OptionSet<ScrollCoordinationRole>, OptionSet<ScrollingNodeChangeFlags>);
     void detachScrollCoordinatedLayer(RenderLayer&, OptionSet<ScrollCoordinationRole>);
+    void detachScrollCoordinatedLayerWithRole(RenderLayer&, ScrollingCoordinator&, ScrollCoordinationRole);
     void reattachSubframeScrollLayers();
     
     FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer&) const;
index 1a332d9..78f2b08 100644 (file)
@@ -1,3 +1,33 @@
+2019-01-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Create "frame hosting" nodes for the scrolling tree
+        https://bugs.webkit.org/show_bug.cgi?id=193753
+
+        Reviewed by Antti Koivisto.
+
+        When the scrolling tree crosses frame boundaries, mutations in the parent frame currently
+        require the iframe's scrolling node to get reparented in a new ancestor, which requires
+        a layer tree walk of the parent frame. This is error-prone, and not very future-proof.
+
+        Fix this by introducing "frame hosting" scrolling tree nodes. These are mostly inert
+        nodes that are owned by the RenderIFrame's layer backing in the parent frame, and exist
+        to provide a consistent parent node for the subframe's scrolling node.
+
+        This patch adds the node types, but does not instantiate them yet.
+
+        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
+        (ArgumentCoder<ScrollingStateFrameHostingNode>::encode):
+        (ArgumentCoder<ScrollingStateFrameHostingNode>::decode):
+        (WebKit::encodeNodeAndDescendants):
+        (WebKit::RemoteScrollingCoordinatorTransaction::decode):
+        (WebKit::dump):
+        * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp:
+        (WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
+        * UIProcess/RemoteLayerTree/RemoteScrollingTree.cpp:
+        (WebKit::RemoteScrollingTree::createScrollingTreeNode):
+        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
+        (WebKit::RemoteScrollingCoordinatorProxy::connectStateNodeLayers):
+
 2019-01-23  Ross Kirsling  <ross.kirsling@sony.com>
 
         [Curl] Unreviewed build fix for r240292 and friends.
index 404a600..e95ca5b 100644 (file)
@@ -30,6 +30,7 @@
 #include "WebCoreArgumentCoders.h"
 #include <WebCore/GraphicsLayer.h>
 #include <WebCore/ScrollingStateFixedNode.h>
+#include <WebCore/ScrollingStateFrameHostingNode.h>
 #include <WebCore/ScrollingStateFrameScrollingNode.h>
 #include <WebCore/ScrollingStateOverflowScrollingNode.h>
 #include <WebCore/ScrollingStateStickyNode.h>
@@ -52,17 +53,22 @@ template<> struct ArgumentCoder<ScrollingStateScrollingNode> {
     static void encode(Encoder&, const ScrollingStateScrollingNode&);
     static bool decode(Decoder&, ScrollingStateScrollingNode&);
 };
-    
+
+template<> struct ArgumentCoder<ScrollingStateFrameHostingNode> {
+    static void encode(Encoder&, const ScrollingStateFrameHostingNode&);
+    static bool decode(Decoder&, ScrollingStateFrameHostingNode&);
+};
+
 template<> struct ArgumentCoder<ScrollingStateFrameScrollingNode> {
     static void encode(Encoder&, const ScrollingStateFrameScrollingNode&);
     static bool decode(Decoder&, ScrollingStateFrameScrollingNode&);
 };
-    
+
 template<> struct ArgumentCoder<ScrollingStateOverflowScrollingNode> {
     static void encode(Encoder&, const ScrollingStateOverflowScrollingNode&);
     static bool decode(Decoder&, ScrollingStateOverflowScrollingNode&);
 };
-    
+
 template<> struct ArgumentCoder<ScrollingStateFixedNode> {
     static void encode(Encoder&, const ScrollingStateFixedNode&);
     static bool decode(Decoder&, ScrollingStateFixedNode&);
@@ -172,6 +178,11 @@ void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, c
         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.horizontalScrollbarLayer());
 }
 
+void ArgumentCoder<ScrollingStateFrameHostingNode>::encode(Encoder& encoder, const ScrollingStateFrameHostingNode& node)
+{
+    encoder << static_cast<const ScrollingStateNode&>(node);
+}
+
 void ArgumentCoder<ScrollingStateOverflowScrollingNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollingNode& node)
 {
     encoder << static_cast<const ScrollingStateScrollingNode&>(node);
@@ -292,6 +303,14 @@ bool ArgumentCoder<ScrollingStateFrameScrollingNode>::decode(Decoder& decoder, S
     return true;
 }
 
+bool ArgumentCoder<ScrollingStateFrameHostingNode>::decode(Decoder& decoder, ScrollingStateFrameHostingNode& node)
+{
+    if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
+        return false;
+
+    return true;
+}
+
 bool ArgumentCoder<ScrollingStateOverflowScrollingNode>::decode(Decoder& decoder, ScrollingStateOverflowScrollingNode& node)
 {
     if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
@@ -357,6 +376,9 @@ static void encodeNodeAndDescendants(IPC::Encoder& encoder, const ScrollingState
     case ScrollingNodeType::Subframe:
         encoder << downcast<ScrollingStateFrameScrollingNode>(stateNode);
         break;
+    case ScrollingNodeType::FrameHosting:
+        encoder << downcast<ScrollingStateFrameHostingNode>(stateNode);
+        break;
     case ScrollingNodeType::Overflow:
         encoder << downcast<ScrollingStateOverflowScrollingNode>(stateNode);
         break;
@@ -443,6 +465,10 @@ bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder)
             if (!decoder.decode(downcast<ScrollingStateFrameScrollingNode>(*newNode)))
                 return false;
             break;
+        case ScrollingNodeType::FrameHosting:
+            if (!decoder.decode(downcast<ScrollingStateFrameHostingNode>(*newNode)))
+                return false;
+            break;
         case ScrollingNodeType::Overflow:
             if (!decoder.decode(downcast<ScrollingStateOverflowScrollingNode>(*newNode)))
                 return false;
@@ -586,6 +612,9 @@ static void dump(TextStream& ts, const ScrollingStateNode& node, bool changedPro
     case ScrollingNodeType::Subframe:
         dump(ts, downcast<ScrollingStateFrameScrollingNode>(node), changedPropertiesOnly);
         break;
+    case ScrollingNodeType::FrameHosting:
+        dump(ts, downcast<ScrollingStateFrameHostingNode>(node), changedPropertiesOnly);
+        break;
     case ScrollingNodeType::Overflow:
         dump(ts, downcast<ScrollingStateOverflowScrollingNode>(node), changedPropertiesOnly);
         break;
index a367e15..a959c93 100644 (file)
@@ -140,6 +140,7 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
                 scrollingStateNode.setScrolledContentsLayer(layerTreeHost.layerForID(scrollingStateNode.scrolledContentsLayer()));
             break;
         }
+        case ScrollingNodeType::FrameHosting:
         case ScrollingNodeType::Fixed:
         case ScrollingNodeType::Sticky:
             break;
index 62a386d..26d9709 100644 (file)
@@ -31,6 +31,7 @@
 #include "RemoteLayerTreeHost.h"
 #include "RemoteScrollingCoordinatorProxy.h"
 #include <WebCore/ScrollingTreeFixedNode.h>
+#include <WebCore/ScrollingTreeFrameHostingNode.h>
 #include <WebCore/ScrollingTreeStickyNode.h>
 
 #if PLATFORM(IOS_FAMILY)
@@ -120,6 +121,8 @@ Ref<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(ScrollingNod
 #else
         return ScrollingTreeFrameScrollingNodeRemoteMac::create(*this, nodeType, nodeID);
 #endif
+    case ScrollingNodeType::FrameHosting:
+        return ScrollingTreeFrameHostingNode::create(*this, nodeID);
     case ScrollingNodeType::Overflow:
 #if PLATFORM(IOS_FAMILY)
         return ScrollingTreeOverflowScrollingNodeIOS::create(*this, nodeID);
index 9a45671..5dc011f 100644 (file)
@@ -87,6 +87,8 @@ void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree&
             if (currNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
                 currNode->setLayer(layerTreeHost.layerForID(currNode->layer()));
             break;
+        case ScrollingNodeType::FrameHosting:
+            break;
         }
     }
 }