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/rendering/RenderObject.h"
30#include "platform/PlatformWheelEvent.h"
31#include "platform/geometry/IntRect.h"
32#include "platform/scroll/ScrollTypes.h"
33#include "wtf/text/WTFString.h"
34
35namespace blink {
36class WebScrollbarLayer;
37}
38
39namespace blink {
40
41typedef unsigned MainThreadScrollingReasons;
42
43class LocalFrame;
44class FrameView;
45class GraphicsLayer;
46class Page;
47class Region;
48class ScrollableArea;
49
50class ScrollingCoordinator {
51public:
52    ~ScrollingCoordinator();
53
54    static PassOwnPtr<ScrollingCoordinator> create(Page*);
55
56    void willBeDestroyed();
57
58    // Return whether this scrolling coordinator handles scrolling for the given frame view.
59    bool coordinatesScrollingForFrameView(FrameView*) const;
60
61    // Called when any frame has done its layout.
62    void notifyLayoutUpdated();
63
64    void updateAfterCompositingChangeIfNeeded();
65
66    void updateHaveWheelEventHandlers();
67    void updateHaveScrollEventHandlers();
68
69    // Should be called whenever the slow repaint objects counter changes between zero and one.
70    void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
71
72    // Should be called whenever the set of fixed objects changes.
73    void frameViewFixedObjectsDidChange(FrameView*);
74
75    // Should be called whenever the root layer for the given frame view changes.
76    void frameViewRootLayerDidChange(FrameView*);
77
78#if OS(MACOSX)
79    // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread.
80    void handleWheelEventPhase(PlatformWheelEventPhase);
81#endif
82
83    enum MainThreadScrollingReasonFlags {
84        HasSlowRepaintObjects = 1 << 0,
85        HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 1,
86        HasNonLayerViewportConstrainedObjects = 1 << 2,
87        ThreadedScrollingDisabled = 1 << 3
88    };
89
90    MainThreadScrollingReasons mainThreadScrollingReasons() const;
91    bool shouldUpdateScrollLayerPositionOnMainThread() const { return mainThreadScrollingReasons() != 0; }
92
93    PassOwnPtr<blink::WebScrollbarLayer> createSolidColorScrollbarLayer(ScrollbarOrientation, int thumbThickness, int trackStart, bool isLeftSideVerticalScrollbar);
94
95    void willDestroyScrollableArea(ScrollableArea*);
96    // Returns true if the coordinator handled this change.
97    bool scrollableAreaScrollLayerDidChange(ScrollableArea*);
98    void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation);
99    void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool);
100    void updateLayerPositionConstraint(RenderLayer*);
101    void touchEventTargetRectsDidChange();
102    void willDestroyRenderLayer(RenderLayer*);
103
104    void updateScrollParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent);
105    void updateClipParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent);
106
107    static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons);
108    String mainThreadScrollingReasonsAsText() const;
109    Region computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame*, const IntPoint& frameLocation) const;
110
111    void updateTouchEventTargetRectsIfNeeded();
112
113    // For testing purposes only. This ScrollingCoordinator is reused between layout test, and must be reset
114    // for the results to be valid.
115    void reset();
116
117protected:
118    explicit ScrollingCoordinator(Page*);
119
120    bool isForMainFrame(ScrollableArea*) const;
121
122    Page* m_page;
123
124    // Dirty flags used to idenfity what really needs to be computed after compositing is updated.
125    bool m_scrollGestureRegionIsDirty;
126    bool m_touchEventTargetRectsAreDirty;
127    bool m_shouldScrollOnMainThreadDirty;
128
129private:
130    bool shouldUpdateAfterCompositingChange() const { return m_scrollGestureRegionIsDirty || m_touchEventTargetRectsAreDirty || frameViewIsDirty(); }
131
132    void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
133
134    bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
135
136    void setShouldHandleScrollGestureOnMainThreadRegion(const Region&);
137    void setTouchEventTargetRects(LayerHitTestRects&);
138    void computeTouchEventTargetRects(LayerHitTestRects&);
139
140    blink::WebScrollbarLayer* addWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation, PassOwnPtr<blink::WebScrollbarLayer>);
141    blink::WebScrollbarLayer* getWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
142    void removeWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
143
144    bool frameViewIsDirty() const;
145
146    typedef HashMap<ScrollableArea*, OwnPtr<blink::WebScrollbarLayer> > ScrollbarMap;
147    ScrollbarMap m_horizontalScrollbars;
148    ScrollbarMap m_verticalScrollbars;
149    HashSet<const RenderLayer*> m_layersWithTouchRects;
150    bool m_wasFrameScrollable;
151
152    // This is retained for testing.
153    MainThreadScrollingReasons m_lastMainThreadScrollingReasons;
154};
155
156} // namespace blink
157
158#endif // ScrollingCoordinator_h
159