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 Frame; 46 class FrameView; 47 class GraphicsLayer; 48 class Page; 49 class Region; 50 class ScrollableArea; 51 class ViewportConstraints; 52 53 class ScrollingCoordinator : public RefCounted<ScrollingCoordinator> { 54 public: 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 // Called when any frame has done its layout. 64 void notifyLayoutUpdated(); 65 66 // Should be called after compositing has been updated. 67 void updateAfterCompositingChange(); 68 69 bool needsToUpdateAfterCompositingChange() const { return m_scrollGestureRegionIsDirty || m_touchEventTargetRectsAreDirty || frameViewIsScrollableIsDirty(); } 70 71 // Should be called whenever a wheel event handler is added or removed in the 72 // frame view's underlying document. 73 void frameViewWheelEventHandlerCountChanged(FrameView*); 74 75 // Should be called whenever the slow repaint objects counter changes between zero and one. 76 void frameViewHasSlowRepaintObjectsDidChange(FrameView*); 77 78 // Should be called whenever the set of fixed objects changes. 79 void frameViewFixedObjectsDidChange(FrameView*); 80 81 // Should be called whenever the root layer for the given frame view changes. 82 void frameViewRootLayerDidChange(FrameView*); 83 84 #if OS(MACOSX) 85 // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread. 86 void handleWheelEventPhase(PlatformWheelEventPhase); 87 #endif 88 89 enum MainThreadScrollingReasonFlags { 90 HasSlowRepaintObjects = 1 << 0, 91 HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 1, 92 HasNonLayerViewportConstrainedObjects = 1 << 2, 93 }; 94 95 MainThreadScrollingReasons mainThreadScrollingReasons() const; 96 bool shouldUpdateScrollLayerPositionOnMainThread() const { return mainThreadScrollingReasons() != 0; } 97 98 PassOwnPtr<blink::WebScrollbarLayer> createSolidColorScrollbarLayer(ScrollbarOrientation, int thumbThickness, bool isLeftSideVerticalScrollbar); 99 100 void willDestroyScrollableArea(ScrollableArea*); 101 // Returns true if the coordinator handled this change. 102 bool scrollableAreaScrollLayerDidChange(ScrollableArea*); 103 void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation); 104 void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool); 105 void updateLayerPositionConstraint(RenderLayer*); 106 void touchEventTargetRectsDidChange(const Document*); 107 void willDestroyRenderLayer(RenderLayer*); 108 109 void updateScrollParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent); 110 void updateClipParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent); 111 112 static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons); 113 String mainThreadScrollingReasonsAsText() const; 114 Region computeShouldHandleScrollGestureOnMainThreadRegion(const Frame*, const IntPoint& frameLocation) const; 115 116 void updateTouchEventTargetRectsIfNeeded(); 117 118 // For testing purposes only. This ScrollingCoordinator is reused between layout test, and must be reset 119 // for the results to be valid. 120 void reset(); 121 122 protected: 123 explicit ScrollingCoordinator(Page*); 124 125 static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*); 126 static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*); 127 static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*); 128 bool isForMainFrame(ScrollableArea*) const; 129 130 unsigned computeCurrentWheelEventHandlerCount(); 131 GraphicsLayer* scrollLayerForFrameView(FrameView*); 132 GraphicsLayer* counterScrollingLayerForFrameView(FrameView*); 133 134 Page* m_page; 135 136 // Dirty flags used to idenfity what really needs to be computed after compositing is updated. 137 bool m_scrollGestureRegionIsDirty; 138 bool m_touchEventTargetRectsAreDirty; 139 140 private: 141 void recomputeWheelEventHandlerCountForFrameView(FrameView*); 142 void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons); 143 144 bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const; 145 void updateShouldUpdateScrollLayerPositionOnMainThread(); 146 147 static blink::WebLayer* scrollingWebLayerForScrollableArea(ScrollableArea*); 148 149 bool touchHitTestingEnabled() const; 150 void setShouldHandleScrollGestureOnMainThreadRegion(const Region&); 151 void setTouchEventTargetRects(const LayerHitTestRects&); 152 void computeTouchEventTargetRects(LayerHitTestRects&); 153 void setWheelEventHandlerCount(unsigned); 154 155 blink::WebScrollbarLayer* addWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation, PassOwnPtr<blink::WebScrollbarLayer>); 156 blink::WebScrollbarLayer* getWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation); 157 void removeWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation); 158 159 bool frameViewIsScrollableIsDirty() const; 160 161 typedef HashMap<ScrollableArea*, OwnPtr<blink::WebScrollbarLayer> > ScrollbarMap; 162 ScrollbarMap m_horizontalScrollbars; 163 ScrollbarMap m_verticalScrollbars; 164 HashSet<const RenderLayer*> m_layersWithTouchRects; 165 bool m_wasFrameScrollable; 166 167 // This is retained for testing. 168 MainThreadScrollingReasons m_lastMainThreadScrollingReasons; 169 }; 170 171 } // namespace WebCore 172 173 #endif // ScrollingCoordinator_h 174