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
35namespace WebCore {
36
37class Page;
38class Scrollbar;
39class ScrollingStateNode;
40class ScrollingStateScrollingNode;
41class ScrollingStateTree;
42
43// ScrollingCoordinator subclass that maintains a ScrollingStateTree and a ScrollingTree,
44// allowing asynchronous scrolling (in another thread or process).
45class AsyncScrollingCoordinator : public ScrollingCoordinator {
46public:
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
71protected:
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
87private:
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
178SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(WebCore::AsyncScrollingCoordinator, isAsyncScrollingCoordinator());
179
180#endif // ENABLE(ASYNC_SCROLLING)
181