WebKit Bugzilla
Attachment 372735 Details for
Bug 198475
: [Nicosia] support async scrolling
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
asyncscroll.patch (text/plain), 51.94 KB, created by
Zan Dobersek
on 2019-06-23 23:48:42 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Zan Dobersek
Created:
2019-06-23 23:48:42 PDT
Size:
51.94 KB
patch
obsolete
>diff --git a/Source/WebCore/PlatformPlayStation.cmake b/Source/WebCore/PlatformPlayStation.cmake >index 7193bc5ae10..d968e6c64e2 100644 >--- a/Source/WebCore/PlatformPlayStation.cmake >+++ b/Source/WebCore/PlatformPlayStation.cmake >@@ -21,6 +21,7 @@ list(APPEND WebCore_SOURCES > page/scrolling/nicosia/ScrollingTreeFixedNode.cpp > page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp > page/scrolling/nicosia/ScrollingTreeNicosia.cpp >+ page/scrolling/nicosia/ScrollingTreePositionedNode.cpp > page/scrolling/nicosia/ScrollingTreeStickyNode.cpp > > page/scrolling/generic/ScrollingThreadGeneric.cpp >diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt >index 33430f903c8..811a332382d 100644 >--- a/Source/WebCore/SourcesGTK.txt >+++ b/Source/WebCore/SourcesGTK.txt >@@ -55,6 +55,7 @@ page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp > page/scrolling/nicosia/ScrollingTreeFixedNode.cpp > page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp > page/scrolling/nicosia/ScrollingTreeNicosia.cpp >+page/scrolling/nicosia/ScrollingTreePositionedNode.cpp > page/scrolling/nicosia/ScrollingTreeStickyNode.cpp > > page/scrolling/generic/ScrollingThreadGeneric.cpp >diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt >index 2f98ffebf02..9998b76ae8b 100644 >--- a/Source/WebCore/SourcesWPE.txt >+++ b/Source/WebCore/SourcesWPE.txt >@@ -52,6 +52,7 @@ page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp > page/scrolling/nicosia/ScrollingTreeFixedNode.cpp > page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp > page/scrolling/nicosia/ScrollingTreeNicosia.cpp >+page/scrolling/nicosia/ScrollingTreePositionedNode.cpp > page/scrolling/nicosia/ScrollingTreeStickyNode.cpp > > page/scrolling/generic/ScrollingThreadGeneric.cpp >diff --git a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp >index 51b356a941f..0b2a7e240e3 100644 >--- a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp >+++ b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp >@@ -34,6 +34,10 @@ > #include "ScrollingTree.h" > #include <wtf/text/TextStream.h> > >+#if USE(NICOSIA) >+#include "NicosiaPlatformLayer.h" >+#endif >+ > namespace WebCore { > > ScrollingTreeScrollingNode::ScrollingTreeScrollingNode(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID) >@@ -97,7 +101,7 @@ void ScrollingTreeScrollingNode::commitStateBeforeChildren(const ScrollingStateN > if (state.hasChangedProperty(ScrollingStateScrollingNode::ExpectsWheelEventTestTrigger)) > m_expectsWheelEventTestTrigger = state.expectsWheelEventTestTrigger(); > >-#if PLATFORM(COCOA) >+#if PLATFORM(COCOA) || USE(NICOSIA) > if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer)) > m_scrollContainerLayer = state.scrollContainerLayer(); > >diff --git a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h >index b22ffa79225..90e23166d9a 100644 >--- a/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h >+++ b/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h >@@ -28,6 +28,7 @@ > #if ENABLE(ASYNC_SCROLLING) > > #include "IntRect.h" >+#include "PlatformLayer.h" > #include "ScrollSnapOffsetsInfo.h" > #include "ScrollTypes.h" > #include "ScrollableArea.h" >@@ -130,6 +131,9 @@ protected: > > bool expectsWheelEventTestTrigger() const { return m_expectsWheelEventTestTrigger; } > >+ PlatformLayer* scrollContainerLayer() const { return m_scrollContainerLayer.get(); } >+ PlatformLayer* scrolledContentsLayer() const { return m_scrolledContentsLayer.get(); } >+ > LayoutPoint parentToLocalPoint(LayoutPoint) const override; > LayoutPoint localToContentsPoint(LayoutPoint) const override; > >@@ -155,6 +159,9 @@ private: > #if PLATFORM(COCOA) > RetainPtr<CALayer> m_scrollContainerLayer; > RetainPtr<CALayer> m_scrolledContentsLayer; >+#elif USE(NICOSIA) >+ RefPtr<Nicosia::PlatformLayer> m_scrollContainerLayer; >+ RefPtr<Nicosia::PlatformLayer> m_scrolledContentsLayer; > #endif > }; > >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp >index 0d343ab6408..470ae5a6d9b 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingCoordinatorNicosia.cpp >@@ -58,7 +58,9 @@ void ScrollingCoordinatorNicosia::pageDestroyed() > > m_scrollingStateTreeCommitterTimer.stop(); > >- releaseScrollingTree(); >+ // Invalidating the scrolling tree will break the reference cycle between the ScrollingCoordinator and ScrollingTree objects. >+ RefPtr<ThreadedScrollingTree> scrollingTree = static_pointer_cast<ThreadedScrollingTree>(releaseScrollingTree()); >+ ScrollingThread::dispatch([scrollingTree] { scrollingTree->invalidate(); }); > } > > void ScrollingCoordinatorNicosia::commitTreeStateIfNeeded() >@@ -80,12 +82,16 @@ void ScrollingCoordinatorNicosia::scheduleTreeStateCommit() > > void ScrollingCoordinatorNicosia::commitTreeState() > { >+ willCommitTree(); >+ > if (!scrollingStateTree()->hasChangedProperties()) > return; > > RefPtr<ThreadedScrollingTree> threadedScrollingTree = downcast<ThreadedScrollingTree>(scrollingTree()); > > auto treeState = scrollingStateTree()->commit(LayerRepresentation::PlatformLayerRepresentation); >+ threadedScrollingTree->incrementPendingCommitCount(); >+ > ScrollingThread::dispatch([threadedScrollingTree, treeState = WTFMove(treeState)]() mutable { > threadedScrollingTree->commitTreeState(WTFMove(treeState)); > }); >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp >index b5328eb4372..55c5e60596e 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingStateNodeNicosia.cpp >@@ -26,21 +26,23 @@ > #include "config.h" > #include "ScrollingStateNode.h" > >-#include "GraphicsLayer.h" >-#include "NotImplemented.h" >- > #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) > >+#include "NicosiaPlatformLayer.h" >+#include "PlatformLayer.h" >+ > namespace WebCore { > >-void LayerRepresentation::retainPlatformLayer(void*) >+void LayerRepresentation::retainPlatformLayer(void* typelessLayer) > { >- notImplemented(); >+ if (auto* layer = makePlatformLayerTyped(typelessLayer)) >+ layer->ref(); > } > >-void LayerRepresentation::releasePlatformLayer(void*) >+void LayerRepresentation::releasePlatformLayer(void* typelessLayer) > { >- notImplemented(); >+ if (auto* layer = makePlatformLayerTyped(typelessLayer)) >+ layer->deref(); > } > > PlatformLayer* LayerRepresentation::makePlatformLayerTyped(void* typelessLayer) >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp >index c90dbf81e28..70211272c3e 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp >@@ -30,7 +30,12 @@ > > #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) > >+#include "Logging.h" >+#include "ScrollingStateFixedNode.h" > #include "ScrollingTree.h" >+#include "ScrollingTreeOverflowScrollingNode.h" >+#include "NicosiaPlatformLayer.h" >+#include <wtf/text/TextStream.h> > > namespace WebCore { > >@@ -50,12 +55,72 @@ ScrollingTreeFixedNode::~ScrollingTreeFixedNode() > scrollingTree().fixedOrStickyNodeRemoved(); > } > >-void ScrollingTreeFixedNode::commitStateBeforeChildren(const ScrollingStateNode&) >+void ScrollingTreeFixedNode::commitStateBeforeChildren(const ScrollingStateNode& stateNode) > { >+ auto& fixedStateNode = downcast<ScrollingStateFixedNode>(stateNode); >+ >+ if (fixedStateNode.hasChangedProperty(ScrollingStateNode::Layer)) { >+ Nicosia::PlatformLayer* layer = fixedStateNode.layer(); >+ m_scrollLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ >+ if (stateNode.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints)) >+ m_constraints = fixedStateNode.viewportConstraints(); > } > > void ScrollingTreeFixedNode::applyLayerPositions() > { >+ auto computeLayerPosition = [&] { >+ FloatSize overflowScrollDelta; >+ // FIXME: This code is wrong in complex cases where the fixed element is inside a positioned node as >+ // the scroll container order does not match the scrolling tree ancestor order. >+ for (auto* node = parent(); node; node = node->parent()) { >+ if (is<ScrollingTreeFrameScrollingNode>(*node)) { >+ // Fixed nodes are positioned relative to the containing frame scrolling node. >+ // We bail out after finding one. >+ auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*node).layoutViewport(); >+ return m_constraints.layerPositionForViewportRect(layoutViewport) - overflowScrollDelta; >+ } >+ >+ if (is<ScrollingTreeOverflowScrollingNode>(*node)) { >+ // To keep the layer still during async scrolling we adjust by how much the position has changed since layout. >+ auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*node); >+ auto localDelta = overflowNode.lastCommittedScrollPosition() - overflowNode.currentScrollPosition(); >+ overflowScrollDelta += localDelta; >+ } >+ } >+ ASSERT_NOT_REACHED(); >+ return FloatPoint(); >+ }; >+ >+ auto layerPosition = computeLayerPosition(); >+ >+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition); >+ >+ ASSERT(m_scrollLayer); >+ m_scrollLayer->accessStaging( >+ [this, &layerPosition](Nicosia::CompositionLayer::LayerState& state) >+ { >+ state.position = layerPosition; >+ state.delta.positionChanged = true; >+ }); >+} >+ >+void ScrollingTreeFixedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const >+{ >+ ts << "fixed node"; >+ ScrollingTreeNode::dumpProperties(ts, behavior); >+ ts.dumpProperty("fixed constraints", m_constraints); >+ >+#if 0 >+ if (behavior & ScrollingStateTreeAsTextBehaviorIncludeLayerPositions) { >+ FloatRect layerBounds = [m_layer bounds]; >+ FloatPoint anchorPoint = [m_layer anchorPoint]; >+ FloatPoint position = [m_layer position]; >+ FloatPoint layerTopLeft = position - toFloatSize(anchorPoint) * layerBounds.size() + m_constraints.alignmentOffset(); >+ ts.dumpProperty("layer top left", layerTopLeft); >+ } >+#endif > } > > } // namespace WebCore >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h >index 9f8e1e251be..685d97ddd9c 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h >@@ -31,6 +31,13 @@ > > #include "ScrollingTreeNode.h" > >+#include "ScrollingConstraints.h" >+#include <wtf/RefPtr.h> >+ >+namespace Nicosia { >+class CompositionLayer; >+} >+ > namespace WebCore { > > class ScrollingTreeFixedNode final : public ScrollingTreeNode { >@@ -43,8 +50,15 @@ private: > > void commitStateBeforeChildren(const ScrollingStateNode&) override; > void applyLayerPositions() override; >+ >+ void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; >+ >+ FixedPositionViewportConstraints m_constraints; >+ RefPtr<Nicosia::CompositionLayer> m_scrollLayer; > }; > > } // namespace WebCore > >+SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeFixedNode, isFixedNode()) >+ > #endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp >index 1ce4a1adad8..e32f2ddb896 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp >@@ -30,6 +30,11 @@ > > #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) > >+#include "FrameView.h" >+#include "ScrollingStateFrameScrollingNode.h" >+#include "ScrollingTree.h" >+#include "NicosiaPlatformLayer.h" >+ > namespace WebCore { > > Ref<ScrollingTreeFrameScrollingNode> ScrollingTreeFrameScrollingNodeNicosia::create(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID) >@@ -44,12 +49,91 @@ ScrollingTreeFrameScrollingNodeNicosia::ScrollingTreeFrameScrollingNodeNicosia(S > > ScrollingTreeFrameScrollingNodeNicosia::~ScrollingTreeFrameScrollingNodeNicosia() = default; > >-ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent&) >+void ScrollingTreeFrameScrollingNodeNicosia::commitStateBeforeChildren(const ScrollingStateNode& stateNode) >+{ >+ ScrollingTreeFrameScrollingNode::commitStateBeforeChildren(stateNode); >+ const auto& scrollingStateNode = downcast<ScrollingStateFrameScrollingNode>(stateNode); >+ >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Layer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.layer(); >+ m_scrollLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.scrolledContentsLayer(); >+ m_scrolledContentsLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.counterScrollingLayer(); >+ m_counterScrollingLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.insetClipLayer(); >+ m_insetClipLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.contentShadowLayer(); >+ m_contentShadowLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.headerLayer(); >+ m_headerLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer)) { >+ Nicosia::PlatformLayer* layer = scrollingStateNode.footerLayer(); >+ m_footerLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+} >+ >+void ScrollingTreeFrameScrollingNodeNicosia::commitStateAfterChildren(const ScrollingStateNode& stateNode) >+{ >+ ScrollingTreeFrameScrollingNode::commitStateAfterChildren(stateNode); >+ >+ const auto& scrollingStateNode = downcast<ScrollingStateScrollingNode>(stateNode); >+ >+ // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens. >+ if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) { >+ auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User; >+ scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType); >+ } >+} >+ >+ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(const PlatformWheelEvent& wheelEvent) > { >- return ScrollingEventResult::DidNotHandleEvent; >+ if (!canHaveScrollbars()) >+ return ScrollingEventResult::DidNotHandleEvent; >+ >+ if (wheelEvent.deltaX() || wheelEvent.deltaY()) { >+ auto* scrollLayer = scrolledContentsLayer(); >+ ASSERT(scrollLayer); >+ auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer); >+ >+ auto updateScope = compositionLayer.createUpdateScope(); >+ scrollBy({ wheelEvent.deltaX(), -wheelEvent.deltaY() }); >+ } >+ >+ // TODO: >+ // scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID()); >+ // scrollingTree().handleWheelEventPhase(wheelEvent.phase()); >+ return ScrollingEventResult::DidHandleEvent; > } > > void ScrollingTreeFrameScrollingNodeNicosia::repositionScrollingLayers() >+{ >+ auto* scrollLayer = scrolledContentsLayer(); >+ ASSERT(scrollLayer); >+ auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer); >+ >+ auto scrollPosition = currentScrollPosition(); >+ >+ compositionLayer.accessStaging( >+ [&scrollPosition](Nicosia::CompositionLayer::LayerState& state) >+ { >+ state.position = -scrollPosition; >+ state.delta.positionChanged = true; >+ }); >+} >+ >+void ScrollingTreeFrameScrollingNodeNicosia::applyLayerPositions() > { > } > >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h >index 2b5a2be3bce..f7b567eca74 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h >@@ -31,6 +31,12 @@ > > #include "ScrollingTreeFrameScrollingNode.h" > >+#include <wtf/RefPtr.h> >+ >+namespace Nicosia { >+class CompositionLayer; >+} >+ > namespace WebCore { > > class ScrollingTreeFrameScrollingNodeNicosia final : public ScrollingTreeFrameScrollingNode { >@@ -41,9 +47,21 @@ public: > private: > ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree&, ScrollingNodeType, ScrollingNodeID); > >+ void commitStateBeforeChildren(const ScrollingStateNode&) override; >+ void commitStateAfterChildren(const ScrollingStateNode&) override; >+ > ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&) override; > > void repositionScrollingLayers() override; >+ void applyLayerPositions() override; >+ >+ RefPtr<Nicosia::CompositionLayer> m_scrollLayer; >+ RefPtr<Nicosia::CompositionLayer> m_scrolledContentsLayer; >+ RefPtr<Nicosia::CompositionLayer> m_counterScrollingLayer; >+ RefPtr<Nicosia::CompositionLayer> m_insetClipLayer; >+ RefPtr<Nicosia::CompositionLayer> m_contentShadowLayer; >+ RefPtr<Nicosia::CompositionLayer> m_headerLayer; >+ RefPtr<Nicosia::CompositionLayer> m_footerLayer; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp >index cea7146f118..97f886a680e 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp >@@ -33,6 +33,7 @@ > #include "ScrollingTreeFixedNode.h" > #include "ScrollingTreeFrameHostingNode.h" > #include "ScrollingTreeFrameScrollingNodeNicosia.h" >+#include "ScrollingTreePositionedNode.h" > #include "ScrollingTreeStickyNode.h" > > namespace WebCore { >@@ -55,18 +56,18 @@ Ref<ScrollingTreeNode> ScrollingTreeNicosia::createScrollingTreeNode(ScrollingNo > return ScrollingTreeFrameScrollingNodeNicosia::create(*this, nodeType, nodeID); > case ScrollingNodeType::FrameHosting: > return ScrollingTreeFrameHostingNode::create(*this, nodeID); >- case ScrollingNodeType::Overflow: >- // Should not be reached -- caught by ASSERT_NOT_REACHED() below. >+ case ScrollingNodeType::Overflow: // FIXME > break; > case ScrollingNodeType::Fixed: > return ScrollingTreeFixedNode::create(*this, nodeID); > case ScrollingNodeType::Sticky: > return ScrollingTreeStickyNode::create(*this, nodeID); > case ScrollingNodeType::Positioned: >- RELEASE_ASSERT_NOT_REACHED(); >+ return ScrollingTreePositionedNode::create(*this, nodeID); > } > >- RELEASE_ASSERT_NOT_REACHED(); >+ // FIXME: ASSERT_NOT_REACHED(); >+ return ScrollingTreeFixedNode::create(*this, nodeID); > } > > } // namespace WebCore >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.cpp >new file mode 100644 >index 00000000000..d554eceffaa >--- /dev/null >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.cpp >@@ -0,0 +1,120 @@ >+/* >+ * Copyright (C) 2018 Igalia S.L. >+ * >+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT >+ * HOLDER OR 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 "ScrollingTreePositionedNode.h" >+ >+#if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) >+ >+#include "Logging.h" >+#include "NicosiaPlatformLayer.h" >+#include "ScrollingStatePositionedNode.h" >+#include "ScrollingTree.h" >+#include "ScrollingTreeOverflowScrollingNode.h" >+#include <wtf/text/TextStream.h> >+ >+namespace WebCore { >+ >+Ref<ScrollingTreePositionedNode> ScrollingTreePositionedNode::create(ScrollingTree& scrollingTree, ScrollingNodeID nodeID) >+{ >+ return adoptRef(*new ScrollingTreePositionedNode(scrollingTree, nodeID)); >+} >+ >+ScrollingTreePositionedNode::ScrollingTreePositionedNode(ScrollingTree& scrollingTree, ScrollingNodeID nodeID) >+ : ScrollingTreeNode(scrollingTree, ScrollingNodeType::Positioned, nodeID) >+{ >+} >+ >+ScrollingTreePositionedNode::~ScrollingTreePositionedNode() = default; >+ >+void ScrollingTreePositionedNode::commitStateBeforeChildren(const ScrollingStateNode& stateNode) >+{ >+ const ScrollingStatePositionedNode& positionedStateNode = downcast<ScrollingStatePositionedNode>(stateNode); >+ >+ if (positionedStateNode.hasChangedProperty(ScrollingStateNode::Layer)) { >+ Nicosia::PlatformLayer* layer = positionedStateNode.layer(); >+ m_scrollLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ >+ if (positionedStateNode.hasChangedProperty(ScrollingStatePositionedNode::RelatedOverflowScrollingNodes)) >+ m_relatedOverflowScrollingNodes = positionedStateNode.relatedOverflowScrollingNodes(); >+ >+ if (positionedStateNode.hasChangedProperty(ScrollingStatePositionedNode::LayoutConstraintData)) >+ m_constraints = positionedStateNode.layoutConstraints(); >+ >+ if (!m_relatedOverflowScrollingNodes.isEmpty()) >+ scrollingTree().nodesWithRelatedOverflow().add(scrollingNodeID()); >+} >+ >+void ScrollingTreePositionedNode::applyLayerPositions() >+{ >+ auto delta = >+ [this] { >+ FloatSize delta; >+ for (auto nodeID : m_relatedOverflowScrollingNodes) { >+ if (auto* node = scrollingTree().nodeForID(nodeID)) { >+ if (is<ScrollingTreeOverflowScrollingNode>(node)) { >+ auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*node); >+ delta += overflowNode.scrollDeltaSinceLastCommit(); >+ } >+ } >+ } >+ return -delta; >+ }(); >+ FloatPoint layerPosition = m_constraints.layerPositionAtLastLayout() - delta; >+ >+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreePositionedNode " << scrollingNodeID() << " applyLayerPositions: overflow delta " << scrollOffsetSinceLastCommit << " moving layer to " << layerPosition); >+ >+ m_scrollLayer->accessStaging( >+ [this, &layerPosition](Nicosia::CompositionLayer::LayerState& state) >+ { >+ state.position = layerPosition - m_constraints.alignmentOffset(); >+ state.delta.positionChanged = true; >+ }); >+} >+ >+void ScrollingTreePositionedNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const >+{ >+ ts << "positioned node"; >+ ScrollingTreeNode::dumpProperties(ts, behavior); >+ >+ ts.dumpProperty("layout constraints", m_constraints); >+ ts.dumpProperty("related overflow nodes", m_relatedOverflowScrollingNodes.size()); >+ >+ if (behavior & ScrollingStateTreeAsTextBehaviorIncludeNodeIDs) { >+ if (!m_relatedOverflowScrollingNodes.isEmpty()) { >+ TextStream::GroupScope scope(ts); >+ ts << "overflow nodes"; >+ for (auto nodeID : m_relatedOverflowScrollingNodes) >+ ts << "\n" << indent << "nodeID " << nodeID; >+ } >+ } >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.h b/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.h >new file mode 100644 >index 00000000000..85e1c778be3 >--- /dev/null >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreePositionedNode.h >@@ -0,0 +1,67 @@ >+/* >+ * Copyright (C) 2018 Igalia S.L. >+ * >+ * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT >+ * HOLDER OR 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(NICOSIA) >+ >+#include "ScrollingConstraints.h" >+#include "ScrollingTreeNode.h" >+#include <wtf/RefPtr.h> >+ >+namespace Nicosia { >+class CompositionLayer; >+} >+ >+namespace WebCore { >+ >+class ScrollingTreePositionedNode : public ScrollingTreeNode { >+public: >+ static Ref<ScrollingTreePositionedNode> create(ScrollingTree&, ScrollingNodeID); >+ virtual ~ScrollingTreePositionedNode(); >+ >+ const Vector<ScrollingNodeID>& relatedOverflowScrollingNodes() const { return m_relatedOverflowScrollingNodes; } >+ >+private: >+ ScrollingTreePositionedNode(ScrollingTree&, ScrollingNodeID); >+ >+ void commitStateBeforeChildren(const ScrollingStateNode&) override; >+ >+ void applyLayerPositions() override; >+ >+ void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; >+ >+ Vector<ScrollingNodeID> m_relatedOverflowScrollingNodes; >+ AbsolutePositionConstraints m_constraints; >+ RefPtr<Nicosia::CompositionLayer> m_scrollLayer; >+}; >+ >+} // namespace WebCore >+ >+SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreePositionedNode, isPositionedNode()) >+ >+#endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp >index d63eaaecf2c..320e9150fa9 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp >@@ -30,7 +30,13 @@ > > #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) > >+#include "Logging.h" >+#include "ScrollingStateStickyNode.h" > #include "ScrollingTree.h" >+#include "ScrollingTreeFrameScrollingNode.h" >+#include "ScrollingTreeOverflowScrollingNode.h" >+#include "NicosiaPlatformLayer.h" >+#include <wtf/text/TextStream.h> > > namespace WebCore { > >@@ -50,12 +56,60 @@ ScrollingTreeStickyNode::~ScrollingTreeStickyNode() > scrollingTree().fixedOrStickyNodeRemoved(); > } > >-void ScrollingTreeStickyNode::commitStateBeforeChildren(const ScrollingStateNode&) >+void ScrollingTreeStickyNode::commitStateBeforeChildren(const ScrollingStateNode& stateNode) > { >+ auto& stickyStateNode = downcast<ScrollingStateStickyNode>(stateNode); >+ >+ if (stickyStateNode.hasChangedProperty(ScrollingStateNode::Layer)) { >+ Nicosia::PlatformLayer* layer = stickyStateNode.layer(); >+ m_scrollLayer = downcast<Nicosia::CompositionLayer>(layer); >+ } >+ >+ if (stateNode.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints)) >+ m_constraints = stickyStateNode.viewportConstraints(); > } > > void ScrollingTreeStickyNode::applyLayerPositions() > { >+ FloatRect constrainingRect; >+ >+ auto* enclosingScrollingNode = parent(); >+ if (is<ScrollingTreeOverflowScrollingNode>(enclosingScrollingNode)) >+ constrainingRect = FloatRect(downcast<ScrollingTreeOverflowScrollingNode>(*enclosingScrollingNode).currentScrollPosition(), m_constraints.constrainingRectAtLastLayout().size()); >+ else if (is<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)) >+ constrainingRect = downcast<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)->layoutViewport(); >+ else >+ return; >+ >+ FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset(); >+ >+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " constrainingRect " << constrainingRect << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition); >+ >+ ASSERT(m_scrollLayer); >+ m_scrollLayer->accessStaging( >+ [this, &layerPosition](Nicosia::CompositionLayer::LayerState& state) >+ { >+ state.position = layerPosition; >+ state.delta.positionChanged = true; >+ }); >+} >+ >+void ScrollingTreeStickyNode::dumpProperties(TextStream& ts, ScrollingStateTreeAsTextBehavior behavior) const >+{ >+ ts << "sticky node"; >+ >+ ScrollingTreeNode::dumpProperties(ts, behavior); >+ ts.dumpProperty("sticky constraints", m_constraints); >+ >+#if 0 >+ if (behavior & ScrollingStateTreeAsTextBehaviorIncludeLayerPositions) { >+ FloatRect layerBounds = [m_layer bounds]; >+ FloatPoint anchorPoint = [m_layer anchorPoint]; >+ FloatPoint position = [m_layer position]; >+ FloatPoint layerTopLeft = position - toFloatSize(anchorPoint) * layerBounds.size() + m_constraints.alignmentOffset(); >+ ts.dumpProperty("layer top left", layerTopLeft); >+ } >+#endif > } > > } // namespace WebCore >diff --git a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h >index a3d191ea9b9..f9521474128 100644 >--- a/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h >+++ b/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h >@@ -31,6 +31,13 @@ > > #include "ScrollingTreeNode.h" > >+#include "ScrollingConstraints.h" >+#include <wtf/RefPtr.h> >+ >+namespace Nicosia { >+class CompositionLayer; >+} >+ > namespace WebCore { > > class ScrollingTreeStickyNode final : public ScrollingTreeNode { >@@ -44,8 +51,14 @@ private: > void commitStateBeforeChildren(const ScrollingStateNode&) override; > void applyLayerPositions() override; > >+ void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; >+ >+ RefPtr<Nicosia::CompositionLayer> m_scrollLayer; >+ StickyPositionViewportConstraints m_constraints; > }; > > } // namespace WebCore > >+SPECIALIZE_TYPE_TRAITS_SCROLLING_NODE(ScrollingTreeStickyNode, isStickyNode()) >+ > #endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA) >diff --git a/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h b/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h >index a3bf287eb8d..01f6a9a994e 100644 >--- a/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h >+++ b/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h >@@ -272,6 +272,13 @@ public: > functor(m_state.committed); > } > >+ template<typename T> >+ void accessStaging(const T& functor) >+ { >+ LockHolder locker(PlatformLayer::m_state.lock); >+ functor(m_state.staging); >+ } >+ > template<typename T> > void accessCommitted(const T& functor) > { >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >index a95382c9d74..2425ad427d1 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp >@@ -236,6 +236,16 @@ void CoordinatedGraphicsLayer::setPosition(const FloatPoint& p) > didChangeGeometry(); > } > >+void CoordinatedGraphicsLayer::syncPosition(const FloatPoint& p) >+{ >+ if (position() == p) >+ return; >+ >+ GraphicsLayer::setPosition(p); >+ m_nicosia.delta.positionChanged = true; >+ setShouldUpdateVisibleRect(); >+} >+ > void CoordinatedGraphicsLayer::setAnchorPoint(const FloatPoint3D& p) > { > if (anchorPoint() == p) >@@ -1206,6 +1216,11 @@ bool CoordinatedGraphicsLayer::usesContentsLayer() const > return m_nicosia.contentLayer || m_compositedImage; > } > >+PlatformLayer* CoordinatedGraphicsLayer::platformLayer() const >+{ >+ return m_nicosia.layer.get(); >+} >+ > } // namespace WebCore > > #endif // USE(COORDINATED_GRAPHICS) >diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >index b5177de8cec..40707d2724a 100644 >--- a/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >+++ b/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h >@@ -72,6 +72,7 @@ public: > bool replaceChild(GraphicsLayer*, Ref<GraphicsLayer>&&) override; > void removeFromParent() override; > void setPosition(const FloatPoint&) override; >+ void syncPosition(const FloatPoint&) override; > void setAnchorPoint(const FloatPoint3D&) override; > void setSize(const FloatSize&) override; > void setTransform(const TransformationMatrix&) override; >@@ -108,6 +109,10 @@ public: > void resumeAnimations() override; > bool usesContentsLayer() const override; > >+#if USE(NICOSIA) >+ PlatformLayer* platformLayer() const override; >+#endif >+ > void syncPendingStateChangesIncludingSubLayers(); > void updateContentBuffersIncludingSubLayers(); > >diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >index 82d2c15490d..ed7028e596e 100644 >--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp >@@ -45,7 +45,7 @@ namespace WebKit { > > PageClientImpl::PageClientImpl(WKWPE::View& view) > : m_view(view) >- , m_scrollGestureController(std::make_unique<ScrollGestureController>()) >+ , m_scrollGestureController(m_view.scrollGestureController()) > { > } > >@@ -212,8 +212,8 @@ void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& touchEvent, b > > auto& page = m_view.page(); > >- if (m_scrollGestureController->handleEvent(touchPoint)) { >- struct wpe_input_axis_event* axisEvent = m_scrollGestureController->axisEvent(); >+ if (m_scrollGestureController.handleEvent(touchPoint)) { >+ struct wpe_input_axis_event* axisEvent = m_scrollGestureController.axisEvent(); > if (axisEvent->type != wpe_input_axis_event_type_null) > page.handleWheelEvent(WebKit::NativeWebWheelEvent(axisEvent, m_view.page().deviceScaleFactor())); > return; >diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >index 7be9b3ee93f..ccf2f4facc6 100644 >--- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >+++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h >@@ -161,8 +161,7 @@ private: > WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override; > > WKWPE::View& m_view; >- >- std::unique_ptr<ScrollGestureController> m_scrollGestureController; >+ ScrollGestureController& m_scrollGestureController; > }; > > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.cpp b/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.cpp >index 1e613aee4d1..2401529946c 100644 >--- a/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.cpp >+++ b/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.cpp >@@ -27,19 +27,40 @@ > #include "ScrollGestureController.h" > > #include <WebCore/Scrollbar.h> >+#include <wtf/glib/RunLoopSourcePriority.h> >+#include <glib.h> >+#include <numeric> > > namespace WebKit { > >+ScrollGestureController::Client::~Client() = default; >+ >+ScrollGestureController::ScrollGestureController(Client& client) >+ : m_client(client) >+{ >+ m_kinetics.timer = std::make_unique<RunLoop::Timer<ScrollGestureController>>(RunLoop::main(), this, &ScrollGestureController::dispatchCallback); >+ m_kinetics.timer->setPriority(RunLoopSourcePriority::LayerFlushTimer); >+} >+ >+ScrollGestureController::~ScrollGestureController() >+{ >+} >+ > bool ScrollGestureController::handleEvent(const struct wpe_input_touch_event_raw* touchPoint) > { > switch (touchPoint->type) { > case wpe_input_touch_event_type_down: >- m_start.time = touchPoint->time; >- m_start.x = touchPoint->x; >- m_start.y = touchPoint->y; >- m_offset.x = touchPoint->x; >- m_offset.y = touchPoint->y; >+ { >+ int32_t x = touchPoint->x; >+ int32_t y = touchPoint->y; >+ m_start = { touchPoint->time, x, y }; >+ m_offset = { x, y }; >+ m_kinetics.last = { touchPoint->time, x, y }; >+ m_kinetics.velocity = { }; >+ m_kinetics.application = { }; >+ m_kinetics.timer->stop(); > return false; >+ } > case wpe_input_touch_event_type_motion: > if (!m_handling) { > int32_t deltaX = touchPoint->x - m_start.x; >@@ -49,7 +70,7 @@ bool ScrollGestureController::handleEvent(const struct wpe_input_touch_event_raw > int pixelsPerLineStep = WebCore::Scrollbar::pixelsPerLineStep(); > m_handling = std::abs(deltaX) >= pixelsPerLineStep > || std::abs(deltaY) >= pixelsPerLineStep >- || deltaTime >= 200; >+ || deltaTime >= 64; > } > if (m_handling) { > m_axisEvent = { >@@ -59,8 +80,25 @@ bool ScrollGestureController::handleEvent(const struct wpe_input_touch_event_raw > }; > m_offset.x = touchPoint->x; > m_offset.y = touchPoint->y; >+ >+ { >+ auto& last = m_kinetics.last; >+ auto& velocity = m_kinetics.velocity; >+ std::rotate(velocity.x.begin(), velocity.x.begin() + 1, velocity.x.end()); >+ std::rotate(velocity.y.begin(), velocity.y.begin() + 1, velocity.y.end()); >+ std::rotate(velocity.time.begin(), velocity.time.begin() + 1, velocity.time.end()); >+ >+ velocity.x.back() = touchPoint->x - last.x; >+ velocity.y.back() = touchPoint->y - last.y; >+ velocity.time.back() = touchPoint->time - last.time; >+ >+ last = { touchPoint->time, touchPoint->x, touchPoint->y }; >+ } >+ > return true; > } >+ >+ m_kinetics.last = { touchPoint->time, touchPoint->x, touchPoint->y }; > return false; > case wpe_input_touch_event_type_up: > if (m_handling) { >@@ -69,6 +107,20 @@ bool ScrollGestureController::handleEvent(const struct wpe_input_touch_event_raw > wpe_input_axis_event_type_null, > 0, 0, 0, 0, 0, 0 > }; >+ >+ auto& velocity = m_kinetics.velocity; >+ uint32_t accumulatedTime = std::accumulate(velocity.time.begin(), velocity.time.end(), 0); >+ int32_t accumulatedX = std::accumulate(velocity.x.begin(), velocity.x.end(), 0); >+ int32_t accumulatedY = std::accumulate(velocity.y.begin(), velocity.y.end(), 0); >+ double trajectoryX = 1000.0 * accumulatedX / accumulatedTime; >+ double trajectoryY = 1000.0 * accumulatedY / accumulatedTime; >+ >+ m_kinetics.application = { >+ g_get_monotonic_time(), touchPoint->time, touchPoint->time, >+ { m_start.x, trajectoryX, std::abs(trajectoryX * 0.2) }, >+ { m_start.y, trajectoryY, std::abs(trajectoryY * 0.2) } >+ }; >+ m_kinetics.timer->startOneShot(Seconds::fromMilliseconds(15)); > return true; > } > return false; >@@ -77,4 +129,42 @@ bool ScrollGestureController::handleEvent(const struct wpe_input_touch_event_raw > } > } > >+void ScrollGestureController::dispatchCallback() >+{ >+ uint32_t timeOffset = (g_get_monotonic_time() - m_kinetics.application.baseMonotonicTime) / 1000; >+ uint32_t time = m_kinetics.application.baseTime + timeOffset; >+ uint32_t timeDelta = time - m_kinetics.application.lastTime; >+ m_kinetics.application.lastTime = time; >+ >+ double trajectoryXValue = 0; >+ if (timeOffset < m_kinetics.application.x.duration) { >+ trajectoryXValue = -std::pow(double(timeOffset) / m_kinetics.application.x.duration, 2) + 1; >+ trajectoryXValue = std::max<double>(trajectoryXValue, 0); >+ } >+ >+ double trajectoryYValue = 0; >+ if (timeOffset < m_kinetics.application.y.duration) { >+ trajectoryYValue = -std::pow(double(timeOffset) / m_kinetics.application.y.duration, 2) + 1; >+ trajectoryYValue = std::max<double>(trajectoryYValue, 0); >+ } >+ >+ bool activeTrajectories = !!trajectoryXValue || !!trajectoryYValue; >+ >+ int32_t trajectoryYChange = m_kinetics.application.y.trajectory * trajectoryYValue * timeDelta / 1000.0; >+ if (trajectoryYChange) { >+ struct wpe_input_axis_event axisEvent = { >+ wpe_input_axis_event_type_motion, >+ m_kinetics.application.baseTime + timeOffset, >+ m_kinetics.application.x.coordinate, m_kinetics.application.y.coordinate, >+ 2, trajectoryYChange >+ }; >+ m_client.dispatchAxisEvent(&axisEvent); >+ } >+ >+ // FIXME: Also handle change in the horizontal trajectory. >+ >+ if (activeTrajectories) >+ m_kinetics.timer->startOneShot(Seconds::fromMilliseconds(15)); >+} >+ > } // namespace WebKit >diff --git a/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.h b/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.h >index 9c9f6e9e3b1..626e118aecf 100644 >--- a/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.h >+++ b/Source/WebKit/UIProcess/API/wpe/ScrollGestureController.h >@@ -25,19 +25,34 @@ > > #pragma once > >+#include <array> > #include <wpe/wpe.h> >+#include <wtf/RunLoop.h> > > namespace WebKit { > > class ScrollGestureController { > public: >- ScrollGestureController() = default; >+ class Client { >+ public: >+ virtual ~Client(); >+ >+ virtual void dispatchAxisEvent(struct wpe_input_axis_event*) = 0; >+ }; >+ >+ ScrollGestureController(Client&); >+ ~ScrollGestureController(); > > struct wpe_input_axis_event* axisEvent() { return &m_axisEvent; } > >+ bool isHandling() const { return m_handling; } > bool handleEvent(const struct wpe_input_touch_event_raw*); > > private: >+ void dispatchCallback(); >+ >+ Client& m_client; >+ > struct { > uint32_t time { 0 }; > int32_t x { 0 }; >@@ -49,6 +64,32 @@ private: > int32_t y { 0 }; > } m_offset; > >+ struct { >+ struct { >+ uint32_t time { 0 }; >+ int32_t x { 0 }; >+ int32_t y { 0 }; >+ } last; >+ struct { >+ std::array<int32_t, 4> x; >+ std::array<int32_t, 4> y; >+ std::array<uint32_t, 4> time; >+ } velocity; >+ >+ struct { >+ int64_t baseMonotonicTime { 0 }; >+ uint32_t baseTime { 0 }; >+ uint32_t lastTime { 0 }; >+ struct { >+ int32_t coordinate { 0 }; >+ double trajectory { 0 }; >+ double duration { 0 }; >+ } x, y; >+ } application; >+ >+ std::unique_ptr<RunLoop::Timer<ScrollGestureController>> timer; >+ } m_kinetics; >+ > bool m_handling { false }; > struct wpe_input_axis_event m_axisEvent; > }; >diff --git a/Source/WebKit/UIProcess/API/wpe/WPEView.cpp b/Source/WebKit/UIProcess/API/wpe/WPEView.cpp >index 9aa63404531..9d8e1e718e4 100644 >--- a/Source/WebKit/UIProcess/API/wpe/WPEView.cpp >+++ b/Source/WebKit/UIProcess/API/wpe/WPEView.cpp >@@ -43,6 +43,7 @@ namespace WKWPE { > > View::View(struct wpe_view_backend* backend, const API::PageConfiguration& baseConfiguration) > : m_client(std::make_unique<API::ViewClient>()) >+ , m_scrollGestureController(std::make_unique<ScrollGestureController>(*this)) > , m_pageClient(std::make_unique<PageClientImpl>(*this)) > , m_size { 800, 600 } > , m_viewStateFlags { WebCore::ActivityState::WindowIsActive, WebCore::ActivityState::IsFocused, WebCore::ActivityState::IsVisible, WebCore::ActivityState::IsInWindow } >@@ -157,8 +158,27 @@ View::View(struct wpe_view_backend* backend, const API::PageConfiguration& baseC > // handle_touch_event > [](void* data, struct wpe_input_touch_event* event) > { >- auto& page = reinterpret_cast<View*>(data)->page(); >- page.handleTouchEvent(WebKit::NativeWebTouchEvent(event, page.deviceScaleFactor())); >+ auto& view = *reinterpret_cast<View*>(data); >+ auto& page = view.page(); >+ >+ bool handled = false; >+ >+ WebKit::NativeWebTouchEvent nativeEvent(event, page.deviceScaleFactor()); >+ >+ auto& scrollGestureController = *view.m_scrollGestureController; >+ if (scrollGestureController.isHandling()) { >+ const struct wpe_input_touch_event_raw* touchPoint = nativeEvent.nativeFallbackTouchPoint(); >+ if (touchPoint->type != wpe_input_touch_event_type_null && >+ scrollGestureController.handleEvent(touchPoint)) { >+ handled = true; >+ struct wpe_input_axis_event* axisEvent = scrollGestureController.axisEvent(); >+ if (axisEvent->type != wpe_input_axis_event_type_null) >+ page.handleWheelEvent(WebKit::NativeWebWheelEvent(axisEvent, page.deviceScaleFactor())); >+ } >+ } >+ >+ if (!handled) >+ page.handleTouchEvent(nativeEvent); > }, > // padding > nullptr, >@@ -234,4 +254,10 @@ WebKitWebViewAccessible* View::accessible() const > } > #endif > >+void View::dispatchAxisEvent(struct wpe_input_axis_event* axisEvent) >+{ >+ auto& page = this->page(); >+ page.handleWheelEvent(WebKit::NativeWebWheelEvent(axisEvent, page.deviceScaleFactor())); >+} >+ > } // namespace WKWPE >diff --git a/Source/WebKit/UIProcess/API/wpe/WPEView.h b/Source/WebKit/UIProcess/API/wpe/WPEView.h >index 75ca8579802..3b6fdb4baa9 100644 >--- a/Source/WebKit/UIProcess/API/wpe/WPEView.h >+++ b/Source/WebKit/UIProcess/API/wpe/WPEView.h >@@ -27,6 +27,7 @@ > > #include "APIObject.h" > #include "PageClientImpl.h" >+#include "ScrollGestureController.h" > #include "WebPageProxy.h" > #include <WebCore/ActivityState.h> > #include <memory> >@@ -39,6 +40,7 @@ > #endif > > typedef struct OpaqueJSContext* JSGlobalContextRef; >+struct wpe_input_axis_event; > struct wpe_view_backend; > > namespace API { >@@ -47,13 +49,14 @@ class ViewClient; > > namespace WebKit { > class DownloadProxy; >+class ScrollGestureController; > class WebPageGroup; > class WebProcessPool; > } > > namespace WKWPE { > >-class View : public API::ObjectImpl<API::Object::Type::View> { >+class View : public API::ObjectImpl<API::Object::Type::View>, public WebKit::ScrollGestureController::Client { > public: > static View* create(struct wpe_view_backend* backend, const API::PageConfiguration& configuration) > { >@@ -87,14 +90,20 @@ public: > WebKitWebViewAccessible* accessible() const; > #endif > >+ WebKit::ScrollGestureController& scrollGestureController() const { return *m_scrollGestureController; } >+ > private: > View(struct wpe_view_backend*, const API::PageConfiguration&); > > void setSize(const WebCore::IntSize&); > void setViewState(OptionSet<WebCore::ActivityState::Flag>); > >+ // ScrollGestureController::Client >+ void dispatchAxisEvent(struct wpe_input_axis_event*) override; >+ > std::unique_ptr<API::ViewClient> m_client; > >+ std::unique_ptr<WebKit::ScrollGestureController> m_scrollGestureController; > std::unique_ptr<WebKit::PageClientImpl> m_pageClient; > RefPtr<WebKit::WebPageProxy> m_pageProxy; > WebCore::IntSize m_size; >diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp >index 30f66b04447..993d3d2aeef 100644 >--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp >+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp >@@ -257,6 +257,11 @@ void DrawingAreaCoordinatedGraphics::didChangeViewportAttributes(ViewportAttribu > m_previousLayerTreeHost->didChangeViewportAttributes(WTFMove(attrs)); > } > >+bool DrawingAreaCoordinatedGraphics::supportsAsyncScrolling() >+{ >+ return true; >+} >+ > GraphicsLayerFactory* DrawingAreaCoordinatedGraphics::graphicsLayerFactory() > { > if (!m_layerTreeHost) >diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h >index 5af9d5ea96c..a1df74047e7 100644 >--- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h >+++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.h >@@ -62,6 +62,8 @@ private: > void deviceOrPageScaleFactorChanged() override; > void didChangeViewportAttributes(WebCore::ViewportAttributes&&) override; > >+ bool supportsAsyncScrolling() override; >+ > WebCore::GraphicsLayerFactory* graphicsLayerFactory() override; > void setRootCompositingLayer(WebCore::GraphicsLayer*) override; > void scheduleInitialDeferredPaint() override { }; >diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake >index 6cb8c0c2af1..1e3d2493ca9 100644 >--- a/Source/cmake/OptionsWPE.cmake >+++ b/Source/cmake/OptionsWPE.cmake >@@ -46,7 +46,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON) > # Private options shared with other WebKit ports. Add options here only if > # we need a value different from the default defined in WebKitFeatures.cmake. > # Changing these options is completely unsupported. >-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ASYNC_SCROLLING PRIVATE OFF) >+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ASYNC_SCROLLING PRIVATE ON) > WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CONTENT_EXTENSIONS PRIVATE ON) > WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) > WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MHTML PRIVATE ON)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198475
:
371176
|
371726
|
372735
|
377119