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 "core/platform/PlatformWheelEvent.h"
30#include "core/platform/ScrollTypes.h"
31#include "core/platform/graphics/IntRect.h"
32#include "core/rendering/RenderObject.h"
33#include "wtf/text/WTFString.h"
34
35namespace WebKit {
36class WebLayer;
37class WebScrollbarLayer;
38}
39
40namespace WebCore {
41
42typedef unsigned MainThreadScrollingReasons;
43
44class Document;
45class Frame;
46class FrameView;
47class GraphicsLayer;
48class Page;
49class Region;
50class ScrollableArea;
51class ViewportConstraints;
52
53class ScrollingCoordinator : public RefCounted<ScrollingCoordinator> {
54public:
55    static PassRefPtr<ScrollingCoordinator> create(Page*);
56    ~ScrollingCoordinator();
57
58    void pageDestroyed();
59
60    // Return whether this scrolling coordinator handles scrolling for the given frame view.
61    bool coordinatesScrollingForFrameView(FrameView*) const;
62
63    // Should be called whenever the given frame view has been laid out.
64    void frameViewLayoutUpdated(FrameView*);
65
66    // Should be called whenever a wheel event handler is added or removed in the
67    // frame view's underlying document.
68    void frameViewWheelEventHandlerCountChanged(FrameView*);
69
70    // Should be called whenever the slow repaint objects counter changes between zero and one.
71    void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
72
73    // Should be called whenever the set of fixed objects changes.
74    void frameViewFixedObjectsDidChange(FrameView*);
75
76    // Should be called whenever the root layer for the given frame view changes.
77    void frameViewRootLayerDidChange(FrameView*);
78
79#if OS(DARWIN)
80    // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
81    void handleWheelEventPhase(PlatformWheelEventPhase);
82#endif
83
84    enum MainThreadScrollingReasonFlags {
85        HasSlowRepaintObjects = 1 << 0,
86        HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 1,
87        HasNonLayerViewportConstrainedObjects = 1 << 2,
88    };
89
90    MainThreadScrollingReasons mainThreadScrollingReasons() const;
91    bool shouldUpdateScrollLayerPositionOnMainThread() const { return mainThreadScrollingReasons() != 0; }
92
93    void willDestroyScrollableArea(ScrollableArea*);
94    // Returns true if the coordinator handled this change.
95    bool scrollableAreaScrollLayerDidChange(ScrollableArea*);
96    void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation);
97    void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool);
98    void updateLayerPositionConstraint(RenderLayer*);
99    void touchEventTargetRectsDidChange(const Document*);
100
101    static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons);
102    String mainThreadScrollingReasonsAsText() const;
103    Region computeShouldHandleScrollGestureOnMainThreadRegion(const Frame*, const IntPoint& frameLocation) const;
104
105    class TouchEventTargetRectsObserver {
106    public:
107        virtual void touchEventTargetRectsChanged(const LayerHitTestRects&) = 0;
108    };
109
110    void addTouchEventTargetRectsObserver(TouchEventTargetRectsObserver*);
111    void removeTouchEventTargetRectsObserver(TouchEventTargetRectsObserver*);
112
113protected:
114    explicit ScrollingCoordinator(Page*);
115
116    static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*);
117    static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*);
118    static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*);
119    bool isForMainFrame(ScrollableArea*) const;
120
121    unsigned computeCurrentWheelEventHandlerCount();
122    GraphicsLayer* scrollLayerForFrameView(FrameView*);
123    GraphicsLayer* counterScrollingLayerForFrameView(FrameView*);
124
125    Page* m_page;
126
127private:
128    void recomputeWheelEventHandlerCountForFrameView(FrameView*);
129    void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
130
131    bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
132    void updateShouldUpdateScrollLayerPositionOnMainThread();
133
134    static WebKit::WebLayer* scrollingWebLayerForScrollableArea(ScrollableArea*);
135
136    bool touchHitTestingEnabled() const;
137    void setShouldHandleScrollGestureOnMainThreadRegion(const Region&);
138    void setTouchEventTargetRects(const LayerHitTestRects&);
139    void computeTouchEventTargetRects(LayerHitTestRects&);
140    void setWheelEventHandlerCount(unsigned);
141
142    WebKit::WebScrollbarLayer* addWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation, PassOwnPtr<WebKit::WebScrollbarLayer>);
143    WebKit::WebScrollbarLayer* getWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
144    void removeWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
145
146
147    typedef HashMap<ScrollableArea*, OwnPtr<WebKit::WebScrollbarLayer> > ScrollbarMap;
148    ScrollbarMap m_horizontalScrollbars;
149    ScrollbarMap m_verticalScrollbars;
150
151    HashSet<TouchEventTargetRectsObserver*> m_touchEventTargetRectsObservers;
152};
153
154} // namespace WebCore
155
156#endif // ScrollingCoordinator_h
157