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 "IntRect.h" 30#include "LayoutRect.h" 31#include "PlatformWheelEvent.h" 32#include "RenderObject.h" 33#include "ScrollTypes.h" 34#include <wtf/Forward.h> 35 36#if ENABLE(ASYNC_SCROLLING) 37#include <wtf/HashMap.h> 38#include <wtf/ThreadSafeRefCounted.h> 39#include <wtf/Threading.h> 40#endif 41 42#if PLATFORM(COCOA) 43#include <wtf/RetainPtr.h> 44#endif 45 46namespace WebCore { 47 48typedef unsigned SynchronousScrollingReasons; 49typedef uint64_t ScrollingNodeID; 50 51enum ScrollingNodeType { FrameScrollingNode, OverflowScrollingNode, FixedNode, StickyNode }; 52 53class Document; 54class Frame; 55class FrameView; 56class GraphicsLayer; 57class Page; 58class Region; 59class ScrollableArea; 60class ViewportConstraints; 61 62#if ENABLE(ASYNC_SCROLLING) 63class ScrollingTree; 64#endif 65 66enum SetOrSyncScrollingLayerPosition { 67 SetScrollingLayerPosition, 68 SyncScrollingLayerPosition 69}; 70 71struct ScrollableAreaParameters { 72 ScrollElasticity horizontalScrollElasticity; 73 ScrollElasticity verticalScrollElasticity; 74 75 ScrollbarMode horizontalScrollbarMode; 76 ScrollbarMode verticalScrollbarMode; 77 78 bool hasEnabledHorizontalScrollbar; 79 bool hasEnabledVerticalScrollbar; 80 81 ScrollableAreaParameters() 82 : horizontalScrollElasticity(ScrollElasticityNone) 83 , verticalScrollElasticity(ScrollElasticityNone) 84 , horizontalScrollbarMode(ScrollbarAuto) 85 , verticalScrollbarMode(ScrollbarAuto) 86 , hasEnabledHorizontalScrollbar(false) 87 , hasEnabledVerticalScrollbar(false) 88 { 89 } 90 91 bool operator==(const ScrollableAreaParameters& other) const 92 { 93 return horizontalScrollElasticity == other.horizontalScrollElasticity 94 && verticalScrollElasticity == other.verticalScrollElasticity 95 && horizontalScrollbarMode == other.horizontalScrollbarMode 96 && verticalScrollbarMode == other.verticalScrollbarMode 97 && hasEnabledHorizontalScrollbar == other.hasEnabledHorizontalScrollbar 98 && hasEnabledVerticalScrollbar == other.hasEnabledVerticalScrollbar; 99 } 100}; 101 102class ScrollingCoordinator : public ThreadSafeRefCounted<ScrollingCoordinator> { 103public: 104 static PassRefPtr<ScrollingCoordinator> create(Page*); 105 virtual ~ScrollingCoordinator(); 106 107 virtual void pageDestroyed(); 108 109 virtual bool isAsyncScrollingCoordinator() const { return false; } 110 virtual bool isRemoteScrollingCoordinator() const { return false; } 111 112 // Return whether this scrolling coordinator handles scrolling for the given frame view. 113 virtual bool coordinatesScrollingForFrameView(FrameView*) const; 114 115 // Should be called whenever the given frame view has been laid out. 116 virtual void frameViewLayoutUpdated(FrameView*) { } 117 118 // Should be called whenever a wheel event handler is added or removed in the 119 // frame view's underlying document. 120 void frameViewWheelEventHandlerCountChanged(FrameView*); 121 122 // Should be called whenever the slow repaint objects counter changes between zero and one. 123 void frameViewHasSlowRepaintObjectsDidChange(FrameView*); 124 125 // Should be called whenever the set of fixed objects changes. 126 void frameViewFixedObjectsDidChange(FrameView*); 127 128 // Called whenever the non-fast scrollable region changes for reasons other than layout. 129 virtual void frameViewNonFastScrollableRegionChanged(FrameView*) { } 130 131 // Should be called whenever the root layer for the given frame view changes. 132 virtual void frameViewRootLayerDidChange(FrameView*); 133 134 // Return whether this scrolling coordinator can keep fixed position layers fixed to their 135 // containers while scrolling. 136 virtual bool supportsFixedPositionLayers() const { return false; } 137 138#if PLATFORM(COCOA) 139 // Dispatched by the scrolling tree during handleWheelEvent. This is required as long as scrollbars are painted on the main thread. 140 void handleWheelEventPhase(PlatformWheelEventPhase); 141#endif 142 143#if ENABLE(WEB_REPLAY) 144 // Called when the page transitions between executing normally and deterministically. 145 void replaySessionStateDidChange(); 146#endif 147 148 // Force all scroll layer position updates to happen on the main thread. 149 void setForceSynchronousScrollLayerPositionUpdates(bool); 150 151 // These virtual functions are currently unique to the threaded scrolling architecture. 152 // Their meaningful implementations are in ScrollingCoordinatorMac. 153 virtual void commitTreeStateIfNeeded() { } 154 virtual bool requestScrollPositionUpdate(FrameView*, const IntPoint&) { return false; } 155 virtual bool handleWheelEvent(FrameView*, const PlatformWheelEvent&) { return true; } 156 virtual ScrollingNodeID attachToStateTree(ScrollingNodeType, ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; } 157 virtual void detachFromStateTree(ScrollingNodeID) { } 158 virtual void clearStateTree() { } 159 virtual void updateViewportConstrainedNode(ScrollingNodeID, const ViewportConstraints&, GraphicsLayer*) { } 160 161 struct ScrollingGeometry { 162 FloatSize scrollableAreaSize; 163 FloatSize contentSize; 164 FloatSize reachableContentSize; // Smaller than contentSize when overflow is hidden on one axis. 165 FloatPoint scrollPosition; 166 IntPoint scrollOrigin; 167 }; 168 169 virtual void updateFrameScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, GraphicsLayer* /*counterScrollingLayer*/, GraphicsLayer* /*insetClipLayer*/, const ScrollingGeometry* = nullptr) { } 170 virtual void updateOverflowScrollingNode(ScrollingNodeID, GraphicsLayer* /*scrollLayer*/, GraphicsLayer* /*scrolledContentsLayer*/, const ScrollingGeometry* = nullptr) { } 171 virtual void syncChildPositions(const LayoutRect&) { } 172 virtual String scrollingStateTreeAsText() const; 173 virtual bool isRubberBandInProgress() const { return false; } 174 virtual void setScrollPinningBehavior(ScrollPinningBehavior) { } 175 176 // Generated a unique id for scroll layers. 177 ScrollingNodeID uniqueScrollLayerID(); 178 179 enum MainThreadScrollingReasonFlags { 180 ForcedOnMainThread = 1 << 0, 181 HasSlowRepaintObjects = 1 << 1, 182 HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2, 183 HasNonLayerViewportConstrainedObjects = 1 << 3, 184 IsImageDocument = 1 << 4 185 }; 186 187 SynchronousScrollingReasons synchronousScrollingReasons(FrameView*) const; 188 bool shouldUpdateScrollLayerPositionSynchronously() const; 189 190 virtual void willDestroyScrollableArea(ScrollableArea*) { } 191 virtual void scrollableAreaScrollLayerDidChange(ScrollableArea*) { } 192 virtual void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation) { } 193 194 static String synchronousScrollingReasonsAsText(SynchronousScrollingReasons); 195 String synchronousScrollingReasonsAsText() const; 196 197 Region computeNonFastScrollableRegion(const Frame*, const IntPoint& frameLocation) const; 198 199protected: 200 explicit ScrollingCoordinator(Page*); 201 202 static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*); 203 static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*); 204 static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*); 205 206 unsigned computeCurrentWheelEventHandlerCount(); 207 GraphicsLayer* scrollLayerForFrameView(FrameView*); 208 GraphicsLayer* counterScrollingLayerForFrameView(FrameView*); 209 GraphicsLayer* insetClipLayerForFrameView(FrameView*); 210 GraphicsLayer* rootContentLayerForFrameView(FrameView*); 211 GraphicsLayer* contentShadowLayerForFrameView(FrameView*); 212 GraphicsLayer* headerLayerForFrameView(FrameView*); 213 GraphicsLayer* footerLayerForFrameView(FrameView*); 214 215 Page* m_page; // FIXME: ideally this would be a reference but it gets nulled on async teardown. 216 217private: 218 virtual void recomputeWheelEventHandlerCountForFrameView(FrameView*) { } 219 virtual void setSynchronousScrollingReasons(SynchronousScrollingReasons) { } 220 221 virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const; 222 void updateSynchronousScrollingReasons(FrameView*); 223 224 bool m_forceSynchronousScrollLayerPositionUpdates; 225}; 226 227#define SCROLLING_COORDINATOR_TYPE_CASTS(ToValueTypeName, predicate) \ 228 TYPE_CASTS_BASE(ToValueTypeName, WebCore::ScrollingCoordinator, value, value->predicate, value.predicate) 229 230} // namespace WebCore 231 232#endif // ScrollingCoordinator_h 233