Skip to content
Permalink
Browse files
[GTK][WPE] Scrolling with mouse wheel doesn't work on iframes with as…
…ync scrolling enabled

https://bugs.webkit.org/show_bug.cgi?id=214179

Reviewed by Žan Doberšek.

Implement ScrollingTree::scrollingNodeForPoint in
ScrollingTreeNicosia. This fixes overflow and iframe scrolling when
async scrolling is enabled on WPE and GTK ports.

* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp:
(WebCore::ScrollingTreeFrameScrollingNodeNicosia::commitStateBeforeChildren):
* page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h:
* page/scrolling/nicosia/ScrollingTreeNicosia.cpp:
(WebCore::collectDescendantLayersAtPoint):
(WebCore::ScrollingTreeNicosia::scrollingNodeForPoint):
* page/scrolling/nicosia/ScrollingTreeNicosia.h:
* page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp:
(WebCore::ScrollingTreeOverflowScrollingNodeNicosia::commitStateBeforeChildren):
* page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h:
* platform/graphics/nicosia/NicosiaPlatformLayer.h:
(Nicosia::CompositionLayer::flushState):
(Nicosia::CompositionLayer::accessPending):


Canonical link: https://commits.webkit.org/231370@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269579 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Chris Lord committed Nov 9, 2020
1 parent e61f165 commit 8a73b592aeda2596daed1cf4ab84519c419ab3a5
Showing 9 changed files with 138 additions and 2 deletions.
@@ -1,3 +1,29 @@
2020-11-09 Chris Lord <clord@igalia.com>

[GTK][WPE] Scrolling with mouse wheel doesn't work on iframes with async scrolling enabled
https://bugs.webkit.org/show_bug.cgi?id=214179

Reviewed by Žan Doberšek.

Implement ScrollingTree::scrollingNodeForPoint in
ScrollingTreeNicosia. This fixes overflow and iframe scrolling when
async scrolling is enabled on WPE and GTK ports.

* page/scrolling/ThreadedScrollingTree.h:
* page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp:
(WebCore::ScrollingTreeFrameScrollingNodeNicosia::commitStateBeforeChildren):
* page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h:
* page/scrolling/nicosia/ScrollingTreeNicosia.cpp:
(WebCore::collectDescendantLayersAtPoint):
(WebCore::ScrollingTreeNicosia::scrollingNodeForPoint):
* page/scrolling/nicosia/ScrollingTreeNicosia.h:
* page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp:
(WebCore::ScrollingTreeOverflowScrollingNodeNicosia::commitStateBeforeChildren):
* page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h:
* platform/graphics/nicosia/NicosiaPlatformLayer.h:
(Nicosia::CompositionLayer::flushState):
(Nicosia::CompositionLayer::accessPending):

2020-11-09 Chris Lord <clord@igalia.com>

REGRESSION(r269503): [GTK][WPE] >200 tests are failing
@@ -77,6 +77,8 @@ class ThreadedScrollingTree : public ScrollingTree {
void reportExposedUnfilledArea(MonotonicTime, unsigned unfilledArea) override;
void reportSynchronousScrollingReasonsChanged(MonotonicTime, OptionSet<SynchronousScrollingReason>) override;

RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;

private:
bool isThreadedScrollingTree() const override { return true; }
void propagateSynchronousScrollingReasons(const HashSet<ScrollingNodeID>&) override;
@@ -91,8 +93,6 @@ class ThreadedScrollingTree : public ScrollingTree {

Seconds maxAllowableRenderingUpdateDurationForSynchronization();

RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;

enum class SynchronizationState : uint8_t {
Idle,
WaitingForRenderingUpdate,
@@ -89,6 +89,16 @@ void ScrollingTreeFrameScrollingNodeNicosia::commitStateBeforeChildren(const Scr
auto* layer = static_cast<Nicosia::PlatformLayer*>(scrollingStateNode.footerLayer());
m_footerLayer = downcast<Nicosia::CompositionLayer>(layer);
}
if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrolledContentsLayer)) {
auto* scrollLayer = static_cast<Nicosia::PlatformLayer*>(scrolledContentsLayer());
ASSERT(scrollLayer);
auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer);
auto updateScope = compositionLayer.createUpdateScope();
compositionLayer.updateState([nodeID = scrollingNodeID()](Nicosia::CompositionLayer::LayerState& state) {
state.scrollingNodeID = nodeID;
state.delta.scrollingNodeChanged = true;
});
}
}

void ScrollingTreeFrameScrollingNodeNicosia::commitStateAfterChildren(const ScrollingStateNode& stateNode)
@@ -47,6 +47,8 @@ class ScrollingTreeFrameScrollingNodeNicosia final : public ScrollingTreeFrameSc
static Ref<ScrollingTreeFrameScrollingNode> create(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
virtual ~ScrollingTreeFrameScrollingNodeNicosia();

RefPtr<Nicosia::CompositionLayer> rootContentsLayer() const { return m_rootContentsLayer; }

private:
ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);

@@ -30,6 +30,8 @@

#if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)

#include "AsyncScrollingCoordinator.h"
#include "NicosiaPlatformLayer.h"
#include "ScrollingTreeFixedNode.h"
#include "ScrollingTreeFrameHostingNode.h"
#include "ScrollingTreeFrameScrollingNodeNicosia.h"
@@ -73,6 +75,68 @@ Ref<ScrollingTreeNode> ScrollingTreeNicosia::createScrollingTreeNode(ScrollingNo
RELEASE_ASSERT_NOT_REACHED();
}

using Nicosia::CompositionLayer;

static void collectDescendantLayersAtPoint(Vector<RefPtr<CompositionLayer>>& layersAtPoint, RefPtr<CompositionLayer> parent, const FloatPoint& point)
{
bool childExistsAtPoint = false;

parent->accessPending([&](const CompositionLayer::LayerState& state) {
for (auto child : state.children) {
bool containsPoint = false;
FloatPoint transformedPoint;
child->accessPending([&](const CompositionLayer::LayerState& childState) {
if (!childState.transform.isInvertible())
return;
float originX = childState.anchorPoint.x() * childState.size.width();
float originY = childState.anchorPoint.y() * childState.size.height();
auto transform = *(TransformationMatrix()
.translate3d(originX + childState.position.x(), originY + childState.position.y(), childState.anchorPoint.z())
.multiply(childState.transform)
.translate3d(-originX, -originY, -childState.anchorPoint.z()).inverse());
auto childPoint = transform.projectPoint(point);
if (FloatRect(FloatPoint(), childState.size).contains(childPoint)) {
containsPoint = true;
transformedPoint.set(childPoint.x(), childPoint.y());
}
});
if (containsPoint) {
childExistsAtPoint = true;
collectDescendantLayersAtPoint(layersAtPoint, child, transformedPoint);
}
}
});

if (!childExistsAtPoint)
layersAtPoint.append(parent);
}

RefPtr<ScrollingTreeNode> ScrollingTreeNicosia::scrollingNodeForPoint(FloatPoint point)
{
auto* rootScrollingNode = rootNode();
if (!rootScrollingNode)
return nullptr;

LayerTreeHitTestLocker layerLocker(m_scrollingCoordinator.get());

auto rootContentsLayer = static_cast<ScrollingTreeFrameScrollingNodeNicosia*>(rootScrollingNode)->rootContentsLayer();
Vector<RefPtr<CompositionLayer>> layersAtPoint;
collectDescendantLayersAtPoint(layersAtPoint, rootContentsLayer, point);

ScrollingTreeNode* returnNode = nullptr;
for (auto layer : WTF::makeReversedRange(layersAtPoint)) {
layer->accessCommitted([&](const CompositionLayer::LayerState& state) {
auto* scrollingNode = nodeForID(state.scrollingNodeID);
if (is<ScrollingTreeScrollingNode>(scrollingNode))
returnNode = scrollingNode;
});
if (returnNode)
break;
}

return returnNode ? returnNode : rootScrollingNode;
}

} // namespace WebCore

#endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)
@@ -41,6 +41,8 @@ class ScrollingTreeNicosia final : public ThreadedScrollingTree {
explicit ScrollingTreeNicosia(AsyncScrollingCoordinator&);

Ref<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) override;

RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint) final;
};

} // namespace WebCore
@@ -56,6 +56,23 @@ ScrollingTreeOverflowScrollingNodeNicosia::ScrollingTreeOverflowScrollingNodeNic

ScrollingTreeOverflowScrollingNodeNicosia::~ScrollingTreeOverflowScrollingNodeNicosia() = default;

void ScrollingTreeOverflowScrollingNodeNicosia::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
{
ScrollingTreeScrollingNode::commitStateBeforeChildren(stateNode);

const auto& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrolledContentsLayer)) {
auto* scrollLayer = static_cast<Nicosia::PlatformLayer*>(scrolledContentsLayer());
ASSERT(scrollLayer);
auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer);
auto updateScope = compositionLayer.createUpdateScope();
compositionLayer.updateState([nodeID = scrollingNodeID()](Nicosia::CompositionLayer::LayerState& state) {
state.scrollingNodeID = nodeID;
state.delta.scrollingNodeChanged = true;
});
}
}

void ScrollingTreeOverflowScrollingNodeNicosia::commitStateAfterChildren(const ScrollingStateNode& stateNode)
{
ScrollingTreeOverflowScrollingNode::commitStateAfterChildren(stateNode);
@@ -44,6 +44,7 @@ class ScrollingTreeOverflowScrollingNodeNicosia final : public ScrollingTreeOver
private:
ScrollingTreeOverflowScrollingNodeNicosia(ScrollingTree&, ScrollingNodeID);

void commitStateBeforeChildren(const ScrollingStateNode&) override;
void commitStateAfterChildren(const ScrollingStateNode&) override;

FloatPoint adjustedScrollPosition(const FloatPoint&, ScrollClamping) const override;
@@ -37,6 +37,7 @@
#include "NicosiaAnimatedBackingStoreClient.h"
#include "NicosiaAnimation.h"
#include "NicosiaSceneIntegration.h"
#include "ScrollTypes.h"
#include "TransformationMatrix.h"
#include <wtf/Function.h>
#include <wtf/Lock.h>
@@ -134,6 +135,7 @@ class CompositionLayer : public PlatformLayer {
bool animatedBackingStoreClientChanged : 1;
bool repaintCounterChanged : 1;
bool debugBorderChanged : 1;
bool scrollingNodeChanged : 1;
};
uint32_t value { 0 };
};
@@ -198,6 +200,8 @@ class CompositionLayer : public PlatformLayer {
float width { 0 };
bool visible { false };
} debugBorder;

WebCore::ScrollingNodeID scrollingNodeID { 0 };
};

template<typename T>
@@ -266,6 +270,9 @@ class CompositionLayer : public PlatformLayer {
if (pending.delta.debugBorderChanged)
staging.debugBorder = pending.debugBorder;

if (pending.delta.scrollingNodeChanged)
staging.scrollingNodeID = pending.scrollingNodeID;

if (pending.delta.backingStoreChanged)
staging.backingStore = pending.backingStore;
if (pending.delta.contentLayerChanged)
@@ -290,6 +297,13 @@ class CompositionLayer : public PlatformLayer {
functor(m_state.committed);
}

template<typename T>
void accessPending(const T& functor)
{
LockHolder locker(PlatformLayer::m_state.lock);
functor(m_state.pending);
}

template<typename T>
void accessCommitted(const T& functor)
{

0 comments on commit 8a73b59

Please sign in to comment.