Changeset 269579 in webkit


Ignore:
Timestamp:
Nov 9, 2020 2:20:55 AM (3 years ago)
Author:
Chris Lord
Message:

[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):

Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r269578 r269579  
     12020-11-09  Chris Lord  <clord@igalia.com>
     2
     3        [GTK][WPE] Scrolling with mouse wheel doesn't work on iframes with async scrolling enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=214179
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Implement ScrollingTree::scrollingNodeForPoint in
     9        ScrollingTreeNicosia. This fixes overflow and iframe scrolling when
     10        async scrolling is enabled on WPE and GTK ports.
     11
     12        * page/scrolling/ThreadedScrollingTree.h:
     13        * page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp:
     14        (WebCore::ScrollingTreeFrameScrollingNodeNicosia::commitStateBeforeChildren):
     15        * page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h:
     16        * page/scrolling/nicosia/ScrollingTreeNicosia.cpp:
     17        (WebCore::collectDescendantLayersAtPoint):
     18        (WebCore::ScrollingTreeNicosia::scrollingNodeForPoint):
     19        * page/scrolling/nicosia/ScrollingTreeNicosia.h:
     20        * page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp:
     21        (WebCore::ScrollingTreeOverflowScrollingNodeNicosia::commitStateBeforeChildren):
     22        * page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h:
     23        * platform/graphics/nicosia/NicosiaPlatformLayer.h:
     24        (Nicosia::CompositionLayer::flushState):
     25        (Nicosia::CompositionLayer::accessPending):
     26
    1272020-11-09  Chris Lord  <clord@igalia.com>
    228
  • trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h

    r268522 r269579  
    7878    void reportSynchronousScrollingReasonsChanged(MonotonicTime, OptionSet<SynchronousScrollingReason>) override;
    7979
     80    RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
     81
    8082private:
    8183    bool isThreadedScrollingTree() const override { return true; }
     
    9193
    9294    Seconds maxAllowableRenderingUpdateDurationForSynchronization();
    93 
    94     RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
    9595
    9696    enum class SynchronizationState : uint8_t {
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp

    r269373 r269579  
    9090        m_footerLayer = downcast<Nicosia::CompositionLayer>(layer);
    9191    }
     92    if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrolledContentsLayer)) {
     93        auto* scrollLayer = static_cast<Nicosia::PlatformLayer*>(scrolledContentsLayer());
     94        ASSERT(scrollLayer);
     95        auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer);
     96        auto updateScope = compositionLayer.createUpdateScope();
     97        compositionLayer.updateState([nodeID = scrollingNodeID()](Nicosia::CompositionLayer::LayerState& state) {
     98            state.scrollingNodeID = nodeID;
     99            state.delta.scrollingNodeChanged = true;
     100        });
     101    }
    92102}
    93103
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.h

    r269373 r269579  
    4848    virtual ~ScrollingTreeFrameScrollingNodeNicosia();
    4949
     50    RefPtr<Nicosia::CompositionLayer> rootContentsLayer() const { return m_rootContentsLayer; }
     51
    5052private:
    5153    ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree&, ScrollingNodeType, ScrollingNodeID);
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.cpp

    r250514 r269579  
    3131#if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)
    3232
     33#include "AsyncScrollingCoordinator.h"
     34#include "NicosiaPlatformLayer.h"
    3335#include "ScrollingTreeFixedNode.h"
    3436#include "ScrollingTreeFrameHostingNode.h"
     
    7476}
    7577
     78using Nicosia::CompositionLayer;
     79
     80static void collectDescendantLayersAtPoint(Vector<RefPtr<CompositionLayer>>& layersAtPoint, RefPtr<CompositionLayer> parent, const FloatPoint& point)
     81{
     82    bool childExistsAtPoint = false;
     83
     84    parent->accessPending([&](const CompositionLayer::LayerState& state) {
     85        for (auto child : state.children) {
     86            bool containsPoint = false;
     87            FloatPoint transformedPoint;
     88            child->accessPending([&](const CompositionLayer::LayerState& childState) {
     89                if (!childState.transform.isInvertible())
     90                    return;
     91                float originX = childState.anchorPoint.x() * childState.size.width();
     92                float originY = childState.anchorPoint.y() * childState.size.height();
     93                auto transform = *(TransformationMatrix()
     94                    .translate3d(originX + childState.position.x(), originY + childState.position.y(), childState.anchorPoint.z())
     95                    .multiply(childState.transform)
     96                    .translate3d(-originX, -originY, -childState.anchorPoint.z()).inverse());
     97                auto childPoint = transform.projectPoint(point);
     98                if (FloatRect(FloatPoint(), childState.size).contains(childPoint)) {
     99                    containsPoint = true;
     100                    transformedPoint.set(childPoint.x(), childPoint.y());
     101                }
     102            });
     103            if (containsPoint) {
     104                childExistsAtPoint = true;
     105                collectDescendantLayersAtPoint(layersAtPoint, child, transformedPoint);
     106            }
     107        }
     108    });
     109
     110    if (!childExistsAtPoint)
     111        layersAtPoint.append(parent);
     112}
     113
     114RefPtr<ScrollingTreeNode> ScrollingTreeNicosia::scrollingNodeForPoint(FloatPoint point)
     115{
     116    auto* rootScrollingNode = rootNode();
     117    if (!rootScrollingNode)
     118        return nullptr;
     119
     120    LayerTreeHitTestLocker layerLocker(m_scrollingCoordinator.get());
     121
     122    auto rootContentsLayer = static_cast<ScrollingTreeFrameScrollingNodeNicosia*>(rootScrollingNode)->rootContentsLayer();
     123    Vector<RefPtr<CompositionLayer>> layersAtPoint;
     124    collectDescendantLayersAtPoint(layersAtPoint, rootContentsLayer, point);
     125
     126    ScrollingTreeNode* returnNode = nullptr;
     127    for (auto layer : WTF::makeReversedRange(layersAtPoint)) {
     128        layer->accessCommitted([&](const CompositionLayer::LayerState& state) {
     129            auto* scrollingNode = nodeForID(state.scrollingNodeID);
     130            if (is<ScrollingTreeScrollingNode>(scrollingNode))
     131                returnNode = scrollingNode;
     132        });
     133        if (returnNode)
     134            break;
     135    }
     136
     137    return returnNode ? returnNode : rootScrollingNode;
     138}
     139
    76140} // namespace WebCore
    77141
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeNicosia.h

    r239667 r269579  
    4242
    4343    Ref<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) override;
     44
     45    RefPtr<ScrollingTreeNode> scrollingNodeForPoint(FloatPoint) final;
    4446};
    4547
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp

    r269184 r269579  
    5757ScrollingTreeOverflowScrollingNodeNicosia::~ScrollingTreeOverflowScrollingNodeNicosia() = default;
    5858
     59void ScrollingTreeOverflowScrollingNodeNicosia::commitStateBeforeChildren(const ScrollingStateNode& stateNode)
     60{
     61    ScrollingTreeScrollingNode::commitStateBeforeChildren(stateNode);
     62
     63    const auto& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(stateNode);
     64    if (scrollingStateNode.hasChangedProperty(ScrollingStateNode::Property::ScrolledContentsLayer)) {
     65        auto* scrollLayer = static_cast<Nicosia::PlatformLayer*>(scrolledContentsLayer());
     66        ASSERT(scrollLayer);
     67        auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer);
     68        auto updateScope = compositionLayer.createUpdateScope();
     69        compositionLayer.updateState([nodeID = scrollingNodeID()](Nicosia::CompositionLayer::LayerState& state) {
     70            state.scrollingNodeID = nodeID;
     71            state.delta.scrollingNodeChanged = true;
     72        });
     73    }
     74}
     75
    5976void ScrollingTreeOverflowScrollingNodeNicosia::commitStateAfterChildren(const ScrollingStateNode& stateNode)
    6077{
  • trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.h

    r268522 r269579  
    4545    ScrollingTreeOverflowScrollingNodeNicosia(ScrollingTree&, ScrollingNodeID);
    4646
     47    void commitStateBeforeChildren(const ScrollingStateNode&) override;
    4748    void commitStateAfterChildren(const ScrollingStateNode&) override;
    4849
  • trunk/Source/WebCore/platform/graphics/nicosia/NicosiaPlatformLayer.h

    r264968 r269579  
    3838#include "NicosiaAnimation.h"
    3939#include "NicosiaSceneIntegration.h"
     40#include "ScrollTypes.h"
    4041#include "TransformationMatrix.h"
    4142#include <wtf/Function.h>
     
    135136                    bool repaintCounterChanged : 1;
    136137                    bool debugBorderChanged : 1;
     138                    bool scrollingNodeChanged : 1;
    137139                };
    138140                uint32_t value { 0 };
     
    199201            bool visible { false };
    200202        } debugBorder;
     203
     204        WebCore::ScrollingNodeID scrollingNodeID { 0 };
    201205    };
    202206
     
    267271            staging.debugBorder = pending.debugBorder;
    268272
     273        if (pending.delta.scrollingNodeChanged)
     274            staging.scrollingNodeID = pending.scrollingNodeID;
     275
    269276        if (pending.delta.backingStoreChanged)
    270277            staging.backingStore = pending.backingStore;
     
    292299
    293300    template<typename T>
     301    void accessPending(const T& functor)
     302    {
     303        LockHolder locker(PlatformLayer::m_state.lock);
     304        functor(m_state.pending);
     305    }
     306
     307    template<typename T>
    294308    void accessCommitted(const T& functor)
    295309    {
Note: See TracChangeset for help on using the changeset viewer.