Remove scrolling tree dependency on wheel event handler counts, and use fast scrollin...
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingTree.h
1 /*
2  * Copyright (C) 2012, 2013, 2014 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 ScrollingTree_h
27 #define ScrollingTree_h
28
29 #if ENABLE(ASYNC_SCROLLING)
30
31 #include "PlatformWheelEvent.h"
32 #include "Region.h"
33 #include "ScrollingCoordinator.h"
34 #include <wtf/Functional.h>
35 #include <wtf/HashMap.h>
36 #include <wtf/ThreadSafeRefCounted.h>
37 #include <wtf/TypeCasts.h>
38
39 namespace WebCore {
40
41 class IntPoint;
42 class ScrollingStateTree;
43 class ScrollingStateNode;
44 class ScrollingTreeNode;
45 class ScrollingTreeScrollingNode;
46
47 class ScrollingTree : public ThreadSafeRefCounted<ScrollingTree> {
48 public:
49     WEBCORE_EXPORT ScrollingTree();
50     WEBCORE_EXPORT virtual ~ScrollingTree();
51
52     enum EventResult {
53         DidNotHandleEvent,
54         DidHandleEvent,
55         SendToMainThread
56     };
57     
58     virtual bool isThreadedScrollingTree() const { return false; }
59     virtual bool isRemoteScrollingTree() const { return false; }
60     virtual bool isScrollingTreeIOS() const { return false; }
61
62     virtual EventResult tryToHandleWheelEvent(const PlatformWheelEvent&) = 0;
63     WEBCORE_EXPORT bool shouldHandleWheelEventSynchronously(const PlatformWheelEvent&);
64     
65     void setMainFrameIsRubberBanding(bool);
66     bool isRubberBandInProgress();
67
68     virtual void invalidate() { }
69     WEBCORE_EXPORT virtual void commitNewTreeState(std::unique_ptr<ScrollingStateTree>);
70
71     void setMainFramePinState(bool pinnedToTheLeft, bool pinnedToTheRight, bool pinnedToTheTop, bool pinnedToTheBottom);
72
73     virtual PassRefPtr<ScrollingTreeNode> createScrollingTreeNode(ScrollingNodeType, ScrollingNodeID) = 0;
74
75     // Called after a scrolling tree node has handled a scroll and updated its layers.
76     // Updates FrameView/RenderLayer scrolling state and GraphicsLayers.
77     virtual void scrollingTreeNodeDidScroll(ScrollingNodeID, const FloatPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition) = 0;
78
79     // Called for requested scroll position updates.
80     virtual void scrollingTreeNodeRequestsScroll(ScrollingNodeID, const FloatPoint& /*scrollPosition*/, bool /*representsProgrammaticScroll*/) { }
81
82     // Delegated scrolling/zooming has caused the viewport to change, so update viewport-constrained layers
83     // (but don't cause scroll events to be fired).
84     WEBCORE_EXPORT virtual void viewportChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale);
85
86     // Delegated scrolling has scrolled a node. Update layer positions on descendant tree nodes,
87     // and call scrollingTreeNodeDidScroll().
88     WEBCORE_EXPORT virtual void scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool inUserInteration);
89
90     FloatPoint mainFrameScrollPosition();
91     
92 #if PLATFORM(IOS)
93     virtual FloatRect fixedPositionRect() = 0;
94     virtual void scrollingTreeNodeWillStartPanGesture() { }
95     virtual void scrollingTreeNodeWillStartScroll() { }
96     virtual void scrollingTreeNodeDidEndScroll() { }
97 #endif
98
99     WEBCORE_EXPORT bool isPointInNonFastScrollableRegion(IntPoint);
100     
101 #if PLATFORM(MAC)
102     virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
103 #endif
104
105     // Can be called from any thread. Will update what edges allow rubber-banding.
106     WEBCORE_EXPORT void setCanRubberBandState(bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom);
107
108     bool rubberBandsAtLeft();
109     bool rubberBandsAtRight();
110     bool rubberBandsAtTop();
111     bool rubberBandsAtBottom();
112     bool isHandlingProgrammaticScroll();
113     
114     void setScrollPinningBehavior(ScrollPinningBehavior);
115     ScrollPinningBehavior scrollPinningBehavior();
116
117     WEBCORE_EXPORT bool willWheelEventStartSwipeGesture(const PlatformWheelEvent&);
118
119     WEBCORE_EXPORT void setScrollingPerformanceLoggingEnabled(bool flag);
120     bool scrollingPerformanceLoggingEnabled();
121
122     ScrollingTreeNode* rootNode() const { return m_rootNode.get(); }
123
124     ScrollingNodeID latchedNode();
125     void setLatchedNode(ScrollingNodeID);
126     void clearLatchedNode();
127
128     bool hasLatchedNode() const { return m_latchedNode; }
129     void setOrClearLatchedNode(const PlatformWheelEvent&, ScrollingNodeID);
130
131     bool hasFixedOrSticky() const { return !!m_fixedOrStickyNodeCount; }
132     void fixedOrStickyNodeAdded() { ++m_fixedOrStickyNodeCount; }
133     void fixedOrStickyNodeRemoved()
134     {
135         ASSERT(m_fixedOrStickyNodeCount);
136         --m_fixedOrStickyNodeCount;
137     }
138     
139 protected:
140     void setMainFrameScrollPosition(FloatPoint);
141     WEBCORE_EXPORT virtual void handleWheelEvent(const PlatformWheelEvent&);
142
143 private:
144     void removeDestroyedNodes(const ScrollingStateTree&);
145     
146     typedef HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>> OrphanScrollingNodeMap;
147     void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&);
148
149     ScrollingTreeNode* nodeForID(ScrollingNodeID) const;
150
151     RefPtr<ScrollingTreeNode> m_rootNode;
152
153     typedef HashMap<ScrollingNodeID, ScrollingTreeNode*> ScrollingTreeNodeMap;
154     ScrollingTreeNodeMap m_nodeMap;
155
156     Mutex m_mutex;
157     Region m_nonFastScrollableRegion;
158     FloatPoint m_mainFrameScrollPosition;
159
160     Mutex m_swipeStateMutex;
161     bool m_rubberBandsAtLeft;
162     bool m_rubberBandsAtRight;
163     bool m_rubberBandsAtTop;
164     bool m_rubberBandsAtBottom;
165     bool m_mainFramePinnedToTheLeft;
166     bool m_mainFramePinnedToTheRight;
167     bool m_mainFramePinnedToTheTop;
168     bool m_mainFramePinnedToTheBottom;
169     bool m_mainFrameIsRubberBanding;
170     ScrollPinningBehavior m_scrollPinningBehavior;
171     ScrollingNodeID m_latchedNode;
172
173     bool m_scrollingPerformanceLoggingEnabled;
174     
175     bool m_isHandlingProgrammaticScroll;
176     unsigned m_fixedOrStickyNodeCount;
177 };
178
179 } // namespace WebCore
180
181 #define SPECIALIZE_TYPE_TRAITS_SCROLLING_TREE(ToValueTypeName, predicate) \
182 SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
183     static bool isType(const WebCore::ScrollingTree& tree) { return tree.predicate; } \
184 SPECIALIZE_TYPE_TRAITS_END()
185 #endif // ENABLE(ASYNC_SCROLLING)
186
187 #endif // ScrollingTree_h