Unreviewed, rolling out r197825.
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingCoordinator.h
1 /*
2  * Copyright (C) 2011, 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 #ifndef ScrollingCoordinator_h
27 #define ScrollingCoordinator_h
28
29 #include "IntRect.h"
30 #include "LayoutRect.h"
31 #include "PlatformWheelEvent.h"
32 #include "RenderObject.h"
33 #include "ScrollTypes.h"
34 #include <wtf/Forward.h>
35 #include <wtf/TypeCasts.h>
36
37 #if ENABLE(ASYNC_SCROLLING)
38 #include <wtf/HashMap.h>
39 #include <wtf/ThreadSafeRefCounted.h>
40 #include <wtf/Threading.h>
41 #endif
42
43 #if PLATFORM(COCOA)
44 #include <wtf/RetainPtr.h>
45 #endif
46
47 #if ENABLE(CSS_SCROLL_SNAP)
48 #include "AxisScrollSnapOffsets.h"
49 #endif
50
51 namespace WebCore {
52
53 typedef unsigned SynchronousScrollingReasons;
54 typedef uint64_t ScrollingNodeID;
55
56 enum ScrollingNodeType { FrameScrollingNode, OverflowScrollingNode, FixedNode, StickyNode };
57
58 class Document;
59 class Frame;
60 class FrameView;
61 class GraphicsLayer;
62 class Page;
63 class Region;
64 class ScrollableArea;
65 class TextStream;
66 class ViewportConstraints;
67
68 #if ENABLE(ASYNC_SCROLLING)
69 class ScrollingTree;
70 #endif
71
72 enum SetOrSyncScrollingLayerPosition {
73     SetScrollingLayerPosition,
74     SyncScrollingLayerPosition
75 };
76
77 struct ScrollableAreaParameters {
78     ScrollElasticity horizontalScrollElasticity;
79     ScrollElasticity verticalScrollElasticity;
80
81     ScrollbarMode horizontalScrollbarMode;
82     ScrollbarMode verticalScrollbarMode;
83
84     bool hasEnabledHorizontalScrollbar;
85     bool hasEnabledVerticalScrollbar;
86     
87     ScrollableAreaParameters()
88         : horizontalScrollElasticity(ScrollElasticityNone)
89         , verticalScrollElasticity(ScrollElasticityNone)
90         , horizontalScrollbarMode(ScrollbarAuto)
91         , verticalScrollbarMode(ScrollbarAuto)
92         , hasEnabledHorizontalScrollbar(false)
93         , hasEnabledVerticalScrollbar(false)
94     {
95     }
96
97     bool operator==(const ScrollableAreaParameters& other) const
98     {
99         return horizontalScrollElasticity == other.horizontalScrollElasticity
100             && verticalScrollElasticity == other.verticalScrollElasticity
101             && horizontalScrollbarMode == other.horizontalScrollbarMode
102             && verticalScrollbarMode == other.verticalScrollbarMode
103             && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar
104             && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar;
105     }
106 };
107
108 class ScrollingCoordinator : public ThreadSafeRefCounted<ScrollingCoordinator> {
109 public:
110     static Ref<ScrollingCoordinator> create(Page*);
111     virtual ~ScrollingCoordinator();
112
113     WEBCORE_EXPORT virtual void pageDestroyed();
114     
115     virtual bool isAsyncScrollingCoordinator() const { return false; }
116     virtual bool isRemoteScrollingCoordinator() const { return false; }
117
118     // Return whether this scrolling coordinator handles scrolling for the given frame view.
119     virtual bool coordinatesScrollingForFrameView(const FrameView&) const;
120
121     // Should be called whenever the given frame view has been laid out.
122     virtual void frameViewLayoutUpdated(FrameView&) { }
123
124     // Should be called whenever the slow repaint objects counter changes between zero and one.
125     void frameViewHasSlowRepaintObjectsDidChange(FrameView&);
126
127     // Should be called whenever the set of fixed objects changes.
128     void frameViewFixedObjectsDidChange(FrameView&);
129
130     // Called whenever the non-fast scrollable region changes for reasons other than layout.
131     virtual void frameViewNonFastScrollableRegionChanged(FrameView&) { }
132
133     // Should be called whenever the root layer for the given frame view changes.
134     virtual void frameViewRootLayerDidChange(FrameView&);
135
136     // Return whether this scrolling coordinator can keep fixed position layers fixed to their
137     // containers while scrolling.
138     virtual bool supportsFixedPositionLayers() const { return false; }
139
140 #if PLATFORM(COCOA)
141     // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
142     void handleWheelEventPhase(PlatformWheelEventPhase);
143 #endif
144
145 #if ENABLE(WEB_REPLAY)
146     // Called when the page transitions between executing normally and deterministically.
147     void replaySessionStateDidChange();
148 #endif
149
150     // Force all scroll layer position updates to happen on the main thread.
151     WEBCORE_EXPORT void setForceSynchronousScrollLayerPositionUpdates(bool);
152
153     // These virtual functions are currently unique to the threaded scrolling architecture. 
154     // Their meaningful implementations are in ScrollingCoordinatorMac.
155     virtual void commitTreeStateIfNeeded() { }
156     virtual bool requestScrollPositionUpdate(FrameView&, const IntPoint&) { return false; }
157     virtual bool handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return true; }
158     virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; }
159     virtual void detachFromStateTree(ScrollingNodeID) { }
160     virtual void clearStateTree() { }
161     virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { }
162
163     struct ScrollingGeometry {
164         FloatSize scrollableAreaSize;
165         FloatSize contentSize;
166         FloatSize reachableContentSize; // Smaller than contentSize when overflow is hidden on one axis.
167         FloatPoint scrollPosition;
168         IntPoint scrollOrigin;
169 #if ENABLE(CSS_SCROLL_SNAP)
170         Vector<LayoutUnit> horizontalSnapOffsets;
171         Vector<LayoutUnit> verticalSnapOffsets;
172         unsigned currentHorizontalSnapPointIndex;
173         unsigned currentVerticalSnapPointIndex;
174 #endif
175     };
176
177     virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { }
178     virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { }
179     virtual void syncChildPositions(const LayoutRect&) { }
180     virtual String scrollingStateTreeAsText() const;
181     virtual bool isRubberBandInProgress() const { return false; }
182     virtual bool isScrollSnapInProgress() const { return false; }
183     virtual void updateScrollSnapPropertiesWithFrameView(const FrameView&) { }
184     virtual void setScrollPinningBehavior(ScrollPinningBehavior) { }
185
186     // Generated a unique id for scroll layers.
187     ScrollingNodeID uniqueScrollLayerID();
188
189     enum MainThreadScrollingReasonFlags {
190         ForcedOnMainThread                                          = 1 << 0,
191         HasSlowRepaintObjects                                       = 1 << 1,
192         HasViewportConstrainedObjectsWithoutSupportingFixedLayers   = 1 << 2,
193         HasNonLayerViewportConstrainedObjects                       = 1 << 3,
194         IsImageDocument                                             = 1 << 4
195     };
196
197     SynchronousScrollingReasons synchronousScrollingReasons(const FrameView&) const;
198     bool shouldUpdateScrollLayerPositionSynchronously() const;
199
200     virtual void willDestroyScrollableArea(ScrollableArea&) { }
201     virtual void scrollableAreaScrollLayerDidChange(ScrollableArea&) { }
202     virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea&, ScrollbarOrientation) { }
203
204     static String synchronousScrollingReasonsAsText(SynchronousScrollingReasons);
205     String synchronousScrollingReasonsAsText() const;
206
207     Region absoluteNonFastScrollableRegion() const;
208
209 protected:
210     explicit ScrollingCoordinator(Page*);
211
212     static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea&);
213
214     GraphicsLayer* scrollLayerForFrameView(FrameView&);
215     GraphicsLayer* counterScrollingLayerForFrameView(FrameView&);
216     GraphicsLayer* insetClipLayerForFrameView(FrameView&);
217     GraphicsLayer* rootContentLayerForFrameView(FrameView&);
218     GraphicsLayer* contentShadowLayerForFrameView(FrameView&);
219     GraphicsLayer* headerLayerForFrameView(FrameView&);
220     GraphicsLayer* footerLayerForFrameView(FrameView&);
221
222     virtual void willCommitTree() { }
223
224     Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown.
225
226 private:
227     virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) { }
228
229     virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const FrameView&) const;
230     void updateSynchronousScrollingReasons(FrameView&);
231
232     Region absoluteNonFastScrollableRegionForFrame(const Frame&) const;
233     
234     bool m_forceSynchronousScrollLayerPositionUpdates { false };
235 };
236
237 WEBCORE_EXPORT TextStream& operator<<(TextStream&, ScrollingNodeType);
238
239 } // namespace WebCore
240
241 #define SPECIALIZE_TYPE_TRAITS_SCROLLING_COORDINATOR(ToValueTypeName, predicate) \
242 SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
243     static bool isType(const WebCore::ScrollingCoordinator& value) { return value.predicate; } \
244 SPECIALIZE_TYPE_TRAITS_END()
245
246 #endif // ScrollingCoordinator_h