/* * Copyright (C) 2011, 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 #include "EventTrackingRegions.h" #include "LayoutRect.h" #include "PlatformWheelEvent.h" #include "ScrollSnapOffsetsInfo.h" #include "ScrollTypes.h" #include "ScrollingCoordinatorTypes.h" #include #include #include #include #include namespace WTF { class TextStream; } namespace WebCore { class AbsolutePositionConstraints; class Document; class Frame; class FrameView; class GraphicsLayer; class Page; class Region; class RenderObject; class RenderLayer; class ScrollableArea; class ViewportConstraints; using FramesPerSecond = unsigned; using PlatformDisplayID = uint32_t; class ScrollingCoordinator : public ThreadSafeRefCounted { WTF_MAKE_FAST_ALLOCATED; public: static Ref create(Page*); virtual ~ScrollingCoordinator(); WEBCORE_EXPORT virtual void pageDestroyed(); virtual bool isAsyncScrollingCoordinator() const { return false; } virtual bool isRemoteScrollingCoordinator() const { return false; } // Return whether this scrolling coordinator handles scrolling for the given frame view. WEBCORE_EXPORT virtual bool coordinatesScrollingForFrameView(const FrameView&) const; // Return whether this scrolling coordinator handles scrolling for the given overflow scroll layer. WEBCORE_EXPORT virtual bool coordinatesScrollingForOverflowLayer(const RenderLayer&) const; // Returns the ScrollingNodeID of the innermost scrolling node that scrolls the renderer. WEBCORE_EXPORT virtual ScrollingNodeID scrollableContainerNodeID(const RenderObject&) const; // Should be called whenever the given frame view has been laid out. virtual void frameViewLayoutUpdated(FrameView&) { } using LayoutViewportOriginOrOverrideRect = WTF::Variant, std::optional>; virtual void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, ScrollType, ViewportRectStability, ScrollingLayerPositionAction) { } // Should be called whenever the set of fixed objects changes. void frameViewFixedObjectsDidChange(FrameView&); // Should be called whenever the FrameView's visual viewport changed. virtual void frameViewVisualViewportChanged(FrameView&) { } // Called whenever the non-fast scrollable region changes for reasons other than layout. virtual void frameViewEventTrackingRegionsChanged(FrameView&) { } // Should be called whenever the root layer for the given frame view changes. virtual void frameViewRootLayerDidChange(FrameView&); // Traverses the scrolling tree, setting layer positions to represent the current scrolled state. virtual void applyScrollingTreeLayerPositions() { } virtual void willStartRenderingUpdate() { } virtual void didCompleteRenderingUpdate() { } #if ENABLE(KINETIC_SCROLLING) // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread. virtual void handleWheelEventPhase(ScrollingNodeID, PlatformWheelEventPhase) { } #endif // Force all scroll layer position updates to happen on the main thread. WEBCORE_EXPORT void setForceSynchronousScrollLayerPositionUpdates(bool); // These virtual functions are currently unique to the threaded scrolling architecture. virtual void commitTreeStateIfNeeded() { } virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped) { return false; } virtual bool handleWheelEventForScrolling(const PlatformWheelEvent&, ScrollingNodeID, std::optional) { return false; } virtual void wheelEventWasProcessedByMainThread(const PlatformWheelEvent&, std::optional) { } // Create an unparented node. virtual ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) { return newNodeID; } // Parent a node in the scrolling tree. This may return a new nodeID if the node type changed. parentID = 0 sets the root node. virtual ScrollingNodeID insertNode(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/, size_t /*childIndex*/ = notFound) { return newNodeID; } // Node will be unparented, but not destroyed. It's the client's responsibility to either re-parent or destroy this node. virtual void unparentNode(ScrollingNodeID) { } // Node will be destroyed, and its children left unparented. virtual void unparentChildrenAndDestroyNode(ScrollingNodeID) { } // Node will be unparented, and it and its children destroyed. virtual void detachAndDestroySubtree(ScrollingNodeID) { } // Destroy the tree, including both parented and unparented nodes. virtual void clearAllNodes() { } virtual ScrollingNodeID parentOfNode(ScrollingNodeID) const { return 0; } virtual Vector childrenOfNode(ScrollingNodeID) const { return { }; } virtual void scrollBySimulatingWheelEventForTesting(ScrollingNodeID, FloatSize) { } struct NodeLayers { GraphicsLayer* layer { nullptr }; GraphicsLayer* scrollContainerLayer { nullptr }; GraphicsLayer* scrolledContentsLayer { nullptr }; GraphicsLayer* counterScrollingLayer { nullptr }; GraphicsLayer* insetClipLayer { nullptr }; GraphicsLayer* rootContentsLayer { nullptr }; GraphicsLayer* horizontalScrollbarLayer { nullptr }; GraphicsLayer* verticalScrollbarLayer { nullptr }; }; virtual void setNodeLayers(ScrollingNodeID, const NodeLayers&) { } virtual void setScrollingNodeScrollableAreaGeometry(ScrollingNodeID, ScrollableArea&) { } virtual void setFrameScrollingNodeState(ScrollingNodeID, const FrameView&) { } virtual void setViewportConstraintedNodeConstraints(ScrollingNodeID, const ViewportConstraints&) { } virtual void setPositionedNodeConstraints(ScrollingNodeID, const AbsolutePositionConstraints&) { } virtual void setRelatedOverflowScrollingNodes(ScrollingNodeID, Vector&&) { } virtual void setSynchronousScrollingReasons(ScrollingNodeID, OptionSet) { } virtual OptionSet synchronousScrollingReasons(ScrollingNodeID) const { return { }; }; bool hasSynchronousScrollingReasons(ScrollingNodeID nodeID) const { return !!synchronousScrollingReasons(nodeID); } virtual void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect&, ScrollingLayerPositionAction) { } virtual String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const; virtual String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const; virtual bool isRubberBandInProgress(ScrollingNodeID) const { return false; } virtual bool isUserScrollInProgress(ScrollingNodeID) const { return false; } virtual bool isScrollSnapInProgress(ScrollingNodeID) const { return false; } virtual void updateScrollSnapPropertiesWithFrameView(const FrameView&) { } virtual void setScrollPinningBehavior(ScrollPinningBehavior) { } virtual bool hasSubscrollers() const { return false; } // Generated a unique id for scrolling nodes. ScrollingNodeID uniqueScrollingNodeID(); bool shouldUpdateScrollLayerPositionSynchronously(const FrameView&) const; virtual void willDestroyScrollableArea(ScrollableArea&) { } virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) { } virtual void windowScreenDidChange(PlatformDisplayID, std::optional /* nominalFramesPerSecond */) { } static String synchronousScrollingReasonsAsText(OptionSet); String synchronousScrollingReasonsAsText() const; EventTrackingRegions absoluteEventTrackingRegions() const; virtual void updateIsMonitoringWheelEventsForFrameView(const FrameView&) { } virtual void startMonitoringWheelEvents(bool /* clearLatchingState */) { } virtual void stopMonitoringWheelEvents() { } protected: explicit ScrollingCoordinator(Page*); GraphicsLayer* scrollContainerLayerForFrameView(FrameView&); GraphicsLayer* scrolledContentsLayerForFrameView(FrameView&); GraphicsLayer* counterScrollingLayerForFrameView(FrameView&); GraphicsLayer* insetClipLayerForFrameView(FrameView&); GraphicsLayer* rootContentsLayerForFrameView(FrameView&); GraphicsLayer* contentShadowLayerForFrameView(FrameView&); GraphicsLayer* headerLayerForFrameView(FrameView&); GraphicsLayer* footerLayerForFrameView(FrameView&); virtual void willCommitTree() { } Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown. private: virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const; void updateSynchronousScrollingReasons(FrameView&); void updateSynchronousScrollingReasonsForAllFrames(); EventTrackingRegions absoluteEventTrackingRegionsForFrame(const Frame&) const; bool m_forceSynchronousScrollLayerPositionUpdates { false }; }; WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollableAreaParameters); WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollingNodeType); WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollingLayerPositionAction); WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ViewportRectStability); } // namespace WebCore #define SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(ToValueTypeName, predicate) \ SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ static bool isType(const WebCore::ScrollingCoordinator& value) { return value.predicate; } \ SPECIALIZE_TYPE_TRAITS_END()