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