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