[iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in...
[WebKit-https.git] / Source / WebCore / page / scrolling / AsyncScrollingCoordinator.h
1 /*
2  * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(ASYNC_SCROLLING)
29
30 #include "ScrollingCoordinator.h"
31 #include "ScrollingTree.h"
32 #include "Timer.h"
33 #include <wtf/RefPtr.h>
34
35 namespace WebCore {
36
37 class Page;
38 class Scrollbar;
39 class ScrollingStateNode;
40 class ScrollingStateScrollingNode;
41 class ScrollingStateTree;
42
43 // ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree,
44 // allowing asynchronous scrolling (in another thread or process).
45 class AsyncScrollingCoordinator : public ScrollingCoordinator {
46 public:
47     static Ref<AsyncScrollingCoordinator> create(Page*);
48     WEBCORE_EXPORT virtual ~AsyncScrollingCoordinator();
49
50     ScrollingTree* scrollingTree() const { return m_scrollingTree.get(); }
51
52     void scrollingStateTreePropertiesChanged();
53
54     WEBCORE_EXPORT void scheduleUpdateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, const Optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction);
55
56 #if PLATFORM(COCOA)
57     WEBCORE_EXPORT void setActiveScrollSnapIndices(ScrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex);
58     void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
59     void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const;
60 #endif
61
62 #if ENABLE(CSS_SCROLL_SNAP)
63     WEBCORE_EXPORT void updateScrollSnapPropertiesWithFrameView(const FrameView&) override;
64 #endif
65
66     WEBCORE_EXPORT void updateExpectsWheelEventTestTriggerWithFrameView(const FrameView&) override;
67
68     void reportExposedUnfilledArea(MonotonicTime, unsigned unfilledArea);
69     void reportSynchronousScrollingReasonsChanged(MonotonicTime, SynchronousScrollingReasons);
70
71 protected:
72     WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
73
74     void setScrollingTree(Ref<ScrollingTree>&& scrollingTree) { m_scrollingTree = WTFMove(scrollingTree); }
75
76     ScrollingStateTree* scrollingStateTree() { return m_scrollingStateTree.get(); }
77
78     RefPtr<ScrollingTree> releaseScrollingTree() { return WTFMove(m_scrollingTree); }
79
80     void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, ScrollType, ScrollingLayerPositionAction);
81
82     WEBCORE_EXPORT String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const override;
83     WEBCORE_EXPORT void willCommitTree() override;
84
85     bool eventTrackingRegionsDirty() const { return m_eventTrackingRegionsDirty; }
86
87 private:
88     bool isAsyncScrollingCoordinator() const override { return true; }
89
90     bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const override { return false; }
91     
92     bool asyncFrameOrOverflowScrollingEnabled() const;
93
94     WEBCORE_EXPORT void frameViewLayoutUpdated(FrameView&) override;
95     WEBCORE_EXPORT void frameViewRootLayerDidChange(FrameView&) override;
96     WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override;
97
98     WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&) override;
99
100     WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override;
101
102     WEBCORE_EXPORT ScrollingNodeID createNode(ScrollingNodeType, ScrollingNodeID newNodeID) override;
103     WEBCORE_EXPORT ScrollingNodeID insertNode(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID, size_t childIndex) override;
104     WEBCORE_EXPORT void unparentNode(ScrollingNodeID) override;
105     WEBCORE_EXPORT void unparentChildrenAndDestroyNode(ScrollingNodeID) override;
106     WEBCORE_EXPORT void detachAndDestroySubtree(ScrollingNodeID) override;
107     WEBCORE_EXPORT void clearAllNodes() override;
108
109     WEBCORE_EXPORT ScrollingNodeID parentOfNode(ScrollingNodeID) const override;
110     WEBCORE_EXPORT Vector<ScrollingNodeID> childrenOfNode(ScrollingNodeID) const override;
111
112     WEBCORE_EXPORT void setNodeLayers(ScrollingNodeID, const NodeLayers&) override;
113
114     WEBCORE_EXPORT void setRectRelativeToParentNode(ScrollingNodeID, const LayoutRect&) override;
115     WEBCORE_EXPORT void setScrollingNodeScrollableAreaGeometry(ScrollingNodeID, ScrollableArea&) override;
116     WEBCORE_EXPORT void setFrameScrollingNodeState(ScrollingNodeID, const FrameView&) override;
117     WEBCORE_EXPORT void setViewportConstraintedNodeConstraints(ScrollingNodeID, const ViewportConstraints&) override;
118     WEBCORE_EXPORT void setPositionedNodeGeometry(ScrollingNodeID, const LayoutConstraints&) override;
119     WEBCORE_EXPORT void setRelatedOverflowScrollingNodes(ScrollingNodeID, Vector<ScrollingNodeID>&&) override;
120
121     WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, ScrollType, ViewportRectStability, ScrollingLayerPositionAction) override;
122     void reconcileScrollPosition(FrameView&, ScrollingLayerPositionAction);
123
124     bool isRubberBandInProgress() const override;
125     void setScrollPinningBehavior(ScrollPinningBehavior) override;
126
127 #if ENABLE(CSS_SCROLL_SNAP)
128     bool isScrollSnapInProgress() const override;
129 #endif
130
131     WEBCORE_EXPORT void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect& viewportRect, ScrollingLayerPositionAction) override;
132     WEBCORE_EXPORT void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) override;
133
134     WEBCORE_EXPORT void setSynchronousScrollingReasons(FrameView&, SynchronousScrollingReasons) final;
135
136     virtual void scheduleTreeStateCommit() = 0;
137
138     void ensureRootStateNodeForFrameView(FrameView&);
139
140     void updateScrollPositionAfterAsyncScrollTimerFired();
141     void setEventTrackingRegionsDirty();
142     void updateEventTrackingRegions();
143     
144     FrameView* frameViewForScrollingNode(ScrollingNodeID) const;
145
146     Timer m_updateNodeScrollPositionTimer;
147
148     struct ScheduledScrollUpdate {
149         ScheduledScrollUpdate() = default;
150         ScheduledScrollUpdate(ScrollingNodeID scrollingNodeID, FloatPoint point, Optional<FloatPoint> viewportOrigin, ScrollingLayerPositionAction udpateAction)
151             : nodeID(scrollingNodeID)
152             , scrollPosition(point)
153             , layoutViewportOrigin(viewportOrigin)
154             , updateLayerPositionAction(udpateAction)
155         { }
156
157         ScrollingNodeID nodeID { 0 };
158         FloatPoint scrollPosition;
159         Optional<FloatPoint> layoutViewportOrigin;
160         ScrollingLayerPositionAction updateLayerPositionAction { ScrollingLayerPositionAction::Sync };
161         
162         bool matchesUpdateType(const ScheduledScrollUpdate& other) const
163         {
164             return nodeID == other.nodeID && updateLayerPositionAction == other.updateLayerPositionAction;
165         }
166     };
167
168     ScheduledScrollUpdate m_scheduledScrollUpdate;
169
170     std::unique_ptr<ScrollingStateTree> m_scrollingStateTree;
171     RefPtr<ScrollingTree> m_scrollingTree;
172
173     bool m_eventTrackingRegionsDirty { false };
174 };
175
176 } // namespace WebCore
177
178 SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator());
179
180 #endif // ENABLE(ASYNC_SCROLLING)