1/*
2 * Copyright (C) 2012, 2013 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(THREADED_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/OwnPtr.h>
37#include <wtf/PassOwnPtr.h>
38#include <wtf/PassRefPtr.h>
39#include <wtf/RefPtr.h>
40#include <wtf/ThreadSafeRefCounted.h>
41
42#if PLATFORM(MAC)
43#include <wtf/RetainPtr.h>
44OBJC_CLASS CALayer;
45#endif
46
47namespace WebCore {
48
49class IntPoint;
50class ScrollingStateNode;
51class ScrollingStateTree;
52class ScrollingTreeNode;
53class ScrollingTreeScrollingNode;
54
55// The ScrollingTree class lives almost exclusively on the scrolling thread and manages the
56// hierarchy of scrollable regions on the page. It's also responsible for dispatching events
57// to the correct scrolling tree nodes or dispatching events back to the ScrollingCoordinator
58// object on the main thread if they can't be handled on the scrolling thread for various reasons.
59class ScrollingTree : public ThreadSafeRefCounted<ScrollingTree> {
60public:
61    static PassRefPtr<ScrollingTree> create(ScrollingCoordinator*);
62    ~ScrollingTree();
63
64    enum EventResult {
65        DidNotHandleEvent,
66        DidHandleEvent,
67        SendToMainThread
68    };
69
70    // Can be called from any thread. Will try to handle the wheel event on the scrolling thread.
71    // Returns true if the wheel event can be handled on the scrolling thread and false if the
72    // event must be sent again to the WebCore event handler.
73    EventResult tryToHandleWheelEvent(const PlatformWheelEvent&);
74    bool hasWheelEventHandlers() const { return m_hasWheelEventHandlers; }
75
76    // Can be called from any thread. Will update the back forward state of the page, used for rubber-banding.
77    void updateBackForwardState(bool canGoBack, bool canGoForward);
78
79    // Must be called from the scrolling thread. Handles the wheel event.
80    void handleWheelEvent(const PlatformWheelEvent&);
81
82    void setMainFrameIsRubberBanding(bool);
83    bool isRubberBandInProgress();
84
85    void invalidate();
86    void commitNewTreeState(PassOwnPtr<ScrollingStateTree>);
87
88    void setMainFramePinState(bool pinnedToTheLeft, bool pinnedToTheRight, bool pinnedToTheTop, bool pinnedToTheBottom);
89
90    void updateMainFrameScrollPosition(const IntPoint& scrollPosition, SetOrSyncScrollingLayerPosition = SyncScrollingLayerPosition);
91    IntPoint mainFrameScrollPosition();
92
93#if PLATFORM(MAC)
94    void handleWheelEventPhase(PlatformWheelEventPhase);
95#endif
96
97    bool canGoBack();
98    bool canGoForward();
99
100    bool rubberBandsAtBottom();
101    void setRubberBandsAtBottom(bool);
102    bool rubberBandsAtTop();
103    void setRubberBandsAtTop(bool);
104
105    void setScrollPinningBehavior(ScrollPinningBehavior);
106    ScrollPinningBehavior scrollPinningBehavior();
107
108    bool willWheelEventStartSwipeGesture(const PlatformWheelEvent&);
109
110    void setScrollingPerformanceLoggingEnabled(bool flag);
111    bool scrollingPerformanceLoggingEnabled();
112
113    ScrollingTreeScrollingNode* rootNode() const { return m_rootNode.get(); }
114
115private:
116    explicit ScrollingTree(ScrollingCoordinator*);
117
118    void removeDestroyedNodes(ScrollingStateTree*);
119    void updateTreeFromStateNode(ScrollingStateNode*);
120
121    RefPtr<ScrollingCoordinator> m_scrollingCoordinator;
122    OwnPtr<ScrollingTreeScrollingNode> m_rootNode;
123
124    typedef HashMap<ScrollingNodeID, ScrollingTreeNode*> ScrollingTreeNodeMap;
125    ScrollingTreeNodeMap m_nodeMap;
126
127    Mutex m_mutex;
128    Region m_nonFastScrollableRegion;
129    IntPoint m_mainFrameScrollPosition;
130    bool m_hasWheelEventHandlers;
131
132    Mutex m_swipeStateMutex;
133    bool m_canGoBack;
134    bool m_canGoForward;
135    bool m_mainFramePinnedToTheLeft;
136    bool m_mainFramePinnedToTheRight;
137    bool m_rubberBandsAtBottom;
138    bool m_rubberBandsAtTop;
139    bool m_mainFramePinnedToTheTop;
140    bool m_mainFramePinnedToTheBottom;
141    bool m_mainFrameIsRubberBanding;
142    ScrollPinningBehavior m_scrollPinningBehavior;
143
144    bool m_scrollingPerformanceLoggingEnabled;
145
146    bool m_isHandlingProgrammaticScroll;
147};
148
149} // namespace WebCore
150
151#endif // ENABLE(THREADED_SCROLLING)
152
153#endif // ScrollingTree_h
154