| /* |
| * Copyright (C) 2014-2015 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 "ScrollingCoordinator.h" |
| #include "ScrollingTree.h" |
| #include "Timer.h" |
| #include <wtf/RefPtr.h> |
| |
| namespace WebCore { |
| |
| class Page; |
| class Scrollbar; |
| class ScrollingStateNode; |
| class ScrollingStateScrollingNode; |
| class ScrollingStateTree; |
| |
| // ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree, |
| // allowing asynchronous scrolling (in another thread or process). |
| class AsyncScrollingCoordinator : public ScrollingCoordinator { |
| public: |
| static Ref<AsyncScrollingCoordinator> create(Page*); |
| WEBCORE_EXPORT virtual ~AsyncScrollingCoordinator(); |
| |
| ScrollingTree* scrollingTree() const { return m_scrollingTree.get(); } |
| |
| void scrollingStateTreePropertiesChanged(); |
| void scrollingThreadAddedPendingUpdate(); |
| |
| void applyPendingScrollUpdates(); |
| |
| WEBCORE_EXPORT void applyScrollUpdate(ScrollUpdate&&, ScrollType = ScrollType::User); |
| |
| #if PLATFORM(COCOA) |
| WEBCORE_EXPORT void handleWheelEventPhase(ScrollingNodeID, PlatformWheelEventPhase) final; |
| |
| WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, std::optional<unsigned> horizontalIndex, std::optional<unsigned> verticalIndex); |
| #endif |
| |
| WEBCORE_EXPORT void updateScrollSnapPropertiesWithFrameView(const FrameView&) override; |
| |
| WEBCORE_EXPORT void updateIsMonitoringWheelEventsForFrameView(const FrameView&) override; |
| |
| void reportExposedUnfilledArea(MonotonicTime, unsigned unfilledArea); |
| void reportSynchronousScrollingReasonsChanged(MonotonicTime, OptionSet<SynchronousScrollingReason>); |
| |
| bool scrollAnimatorEnabled() const; |
| |
| virtual void hasNodeWithAnimatedScrollChanged(bool) { }; |
| |
| protected: |
| WEBCORE_EXPORT AsyncScrollingCoordinator(Page*); |
| |
| void setScrollingTree(Ref<ScrollingTree>&& scrollingTree) { m_scrollingTree = WTFMove(scrollingTree); } |
| |
| ScrollingStateTree* scrollingStateTree() { return m_scrollingStateTree.get(); } |
| |
| RefPtr<ScrollingTree> releaseScrollingTree() { return WTFMove(m_scrollingTree); } |
| |
| WEBCORE_EXPORT String scrollingStateTreeAsText(OptionSet<ScrollingStateTreeAsTextBehavior> = { }) const override; |
| WEBCORE_EXPORT String scrollingTreeAsText(OptionSet<ScrollingStateTreeAsTextBehavior> = { }) const override; |
| WEBCORE_EXPORT void willCommitTree() override; |
| void synchronizeStateFromScrollingTree(); |
| void scheduleRenderingUpdate(); |
| |
| bool eventTrackingRegionsDirty() const { return m_eventTrackingRegionsDirty; } |
| |
| private: |
| bool isAsyncScrollingCoordinator() const override { return true; } |
| |
| bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; } |
| |
| WEBCORE_EXPORT ScrollingNodeID scrollableContainerNodeID(const RenderObject&) const override; |
| |
| WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override; |
| WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override; |
| WEBCORE_EXPORT void frameViewVisualViewportChanged(FrameView&) override; |
| WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override; |
| WEBCORE_EXPORT void frameViewWillBeDetached(FrameView&) override; |
| |
| WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const ScrollPosition&, ScrollType, ScrollClamping) final; |
| WEBCORE_EXPORT bool requestAnimatedScrollToPosition(ScrollableArea&, const ScrollPosition&, ScrollClamping) final; |
| WEBCORE_EXPORT void stopAnimatedScroll(ScrollableArea&) final; |
| |
| WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override; |
| |
| WEBCORE_EXPORT ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) override; |
| WEBCORE_EXPORT ScrollingNodeID insertNode(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) override; |
| WEBCORE_EXPORT void unparentNode(ScrollingNodeID) override; |
| WEBCORE_EXPORT void unparentChildrenAndDestroyNode(ScrollingNodeID) override; |
| WEBCORE_EXPORT void detachAndDestroySubtree(ScrollingNodeID) override; |
| WEBCORE_EXPORT void clearAllNodes() override; |
| |
| WEBCORE_EXPORT ScrollingNodeID parentOfNode(ScrollingNodeID) const override; |
| WEBCORE_EXPORT Vector<ScrollingNodeID> childrenOfNode(ScrollingNodeID) const override; |
| |
| WEBCORE_EXPORT void setNodeLayers(ScrollingNodeID, const NodeLayers&) override; |
| |
| WEBCORE_EXPORT void setScrollingNodeScrollableAreaGeometry(ScrollingNodeID, ScrollableArea&) override; |
| WEBCORE_EXPORT void setFrameScrollingNodeState(ScrollingNodeID, const FrameView&) override; |
| WEBCORE_EXPORT void setViewportConstraintedNodeConstraints(ScrollingNodeID, const ViewportConstraints&) override; |
| WEBCORE_EXPORT void setPositionedNodeConstraints(ScrollingNodeID, const AbsolutePositionConstraints&) override; |
| WEBCORE_EXPORT void setRelatedOverflowScrollingNodes(ScrollingNodeID, Vector<ScrollingNodeID>&&) override; |
| |
| WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, ScrollType, ViewportRectStability, ScrollingLayerPositionAction) override; |
| void reconcileScrollPosition(FrameView&, ScrollingLayerPositionAction); |
| |
| WEBCORE_EXPORT void scrollBySimulatingWheelEventForTesting(ScrollingNodeID, FloatSize) final; |
| |
| WEBCORE_EXPORT bool isUserScrollInProgress(ScrollingNodeID) const override; |
| WEBCORE_EXPORT bool isRubberBandInProgress(ScrollingNodeID) const override; |
| |
| WEBCORE_EXPORT bool isScrollSnapInProgress(ScrollingNodeID) const override; |
| |
| WEBCORE_EXPORT void setScrollPinningBehavior(ScrollPinningBehavior) override; |
| |
| WEBCORE_EXPORT void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect& viewportRect, ScrollingLayerPositionAction) override; |
| WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override; |
| |
| WEBCORE_EXPORT void setSynchronousScrollingReasons(ScrollingNodeID, OptionSet<SynchronousScrollingReason>) final; |
| WEBCORE_EXPORT OptionSet<SynchronousScrollingReason> synchronousScrollingReasons(ScrollingNodeID) const final; |
| |
| WEBCORE_EXPORT void windowScreenDidChange(PlatformDisplayID, std::optional<FramesPerSecond> nominalFramesPerSecond) final; |
| |
| WEBCORE_EXPORT bool hasSubscrollers() const final; |
| |
| virtual void scheduleTreeStateCommit() = 0; |
| |
| void ensureRootStateNodeForFrameView(FrameView&); |
| |
| void setEventTrackingRegionsDirty(); |
| void updateEventTrackingRegions(); |
| |
| void applyScrollPositionUpdate(ScrollUpdate&&, ScrollType); |
| void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, std::optional<FloatPoint> layoutViewportOrigin, ScrollingLayerPositionAction, ScrollType); |
| void animatedScrollDidEndForNode(ScrollingNodeID); |
| |
| FrameView* frameViewForScrollingNode(ScrollingNodeID) const; |
| |
| std::unique_ptr<ScrollingStateTree> m_scrollingStateTree; |
| RefPtr<ScrollingTree> m_scrollingTree; |
| |
| bool m_eventTrackingRegionsDirty { false }; |
| }; |
| |
| #if ENABLE(SCROLLING_THREAD) |
| class LayerTreeHitTestLocker { |
| public: |
| LayerTreeHitTestLocker(ScrollingCoordinator* scrollingCoordinator) |
| { |
| if (is<AsyncScrollingCoordinator>(scrollingCoordinator)) { |
| m_scrollingTree = downcast<AsyncScrollingCoordinator>(*scrollingCoordinator).scrollingTree(); |
| if (m_scrollingTree) |
| m_scrollingTree->lockLayersForHitTesting(); |
| } |
| } |
| |
| ~LayerTreeHitTestLocker() |
| { |
| if (m_scrollingTree) |
| m_scrollingTree->unlockLayersForHitTesting(); |
| } |
| |
| private: |
| RefPtr<ScrollingTree> m_scrollingTree; |
| }; |
| #endif |
| |
| } // namespace WebCore |
| |
| SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator()); |
| |
| #endif // ENABLE(ASYNC_SCROLLING) |