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