Add a new type of scrolling tree node for overflow scrolling
[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     // Force all scroll layer position updates to happen on the main thread.
144     void setForceSynchronousScrollLayerPositionUpdates(bool);
145
146     // These virtual functions are currently unique to the threaded scrolling architecture. 
147     // Their meaningful implementations are in ScrollingCoordinatorMac.
148     virtual void commitTreeStateIfNeeded() { }
149     virtual bool requestScrollPositionUpdate(FrameView*, const IntPoint&) { return false; }
150     virtual bool handleWheelEvent(FrameView*, const PlatformWheelEvent&) { return true; }
151     virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; }
152     virtual void detachFromStateTree(ScrollingNodeID) { }
153     virtual void clearStateTree() { }
154     virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { }
155     virtual void updateScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/) { }
156     virtual void syncChildPositions(const LayoutRect&) { }
157     virtual String scrollingStateTreeAsText() const;
158     virtual bool isRubberBandInProgress() const { return false; }
159     virtual void setScrollPinningBehavior(ScrollPinningBehavior) { }
160
161     // Generated a unique id for scroll layers.
162     ScrollingNodeID uniqueScrollLayerID();
163
164     enum MainThreadScrollingReasonFlags {
165         ForcedOnMainThread = 1 << 0,
166         HasSlowRepaintObjects = 1 << 1,
167         HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2,
168         HasNonLayerViewportConstrainedObjects = 1 << 3,
169         IsImageDocument = 1 << 4
170     };
171
172     SynchronousScrollingReasons synchronousScrollingReasons() const;
173     bool shouldUpdateScrollLayerPositionSynchronously() const { return synchronousScrollingReasons(); }
174
175     virtual void willDestroyScrollableArea(ScrollableArea*) { }
176     virtual void scrollableAreaScrollLayerDidChange(ScrollableArea*) { }
177     virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation) { }
178
179     static String synchronousScrollingReasonsAsText(SynchronousScrollingReasons);
180     String synchronousScrollingReasonsAsText() const;
181
182     Region computeNonFastScrollableRegion(const Frame*, const IntPoint& frameLocation) const;
183
184 protected:
185     explicit ScrollingCoordinator(Page*);
186
187     static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*);
188     static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*);
189     static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*);
190
191     unsigned computeCurrentWheelEventHandlerCount();
192     GraphicsLayer* scrollLayerForFrameView(FrameView*);
193     GraphicsLayer* counterScrollingLayerForFrameView(FrameView*);
194     GraphicsLayer* headerLayerForFrameView(FrameView*);
195     GraphicsLayer* footerLayerForFrameView(FrameView*);
196
197     Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown.
198
199 private:
200     virtual void recomputeWheelEventHandlerCountForFrameView(FrameView*) { }
201     virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) { }
202
203     virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
204     void updateSynchronousScrollingReasons();
205     
206     bool m_forceSynchronousScrollLayerPositionUpdates;
207 };
208
209 #define SCROLLING_COORDINATOR_TYPE_CASTS(ToValueTypeName, predicate) \
210     TYPE_CASTS_BASE(ToValueTypeName, WebCore::ScrollingCoordinator, value, value->predicate, value.predicate)
211
212 } // namespace WebCore
213
214 #endif // ScrollingCoordinator_h