Fix scrolling tree dumping
[WebKit-https.git] / Source / WebCore / page / scrolling / ScrollingStateNode.h
1 /*
2  * Copyright (C) 2012 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 ScrollingStateNode_h
27 #define ScrollingStateNode_h
28
29 #if ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
30
31 #include "GraphicsLayer.h"
32 #include "ScrollingCoordinator.h"
33 #include <wtf/RefCounted.h>
34 #include <wtf/TypeCasts.h>
35 #include <wtf/Vector.h>
36
37 namespace WebCore {
38
39 class GraphicsLayer;
40 class ScrollingStateTree;
41 class TextStream;
42
43 enum ScrollingStateTreeAsTextBehaviorFlags {
44     ScrollingStateTreeAsTextBehaviorNormal               = 0,
45     ScrollingStateTreeAsTextBehaviorIncludeLayerIDs      = 1 << 0,
46     ScrollingStateTreeAsTextBehaviorDebug                = ScrollingStateTreeAsTextBehaviorIncludeLayerIDs
47 };
48 typedef unsigned ScrollingStateTreeAsTextBehavior;
49
50 // Used to allow ScrollingStateNodes to refer to layers in various contexts:
51 // a) Async scrolling, main thread: ScrollingStateNode holds onto a GraphicsLayer, and uses m_layerID
52 //    to detect whether that GraphicsLayer's underlying PlatformLayer changed.
53 // b) Threaded scrolling, commit to scrolling thread: ScrollingStateNode wraps a PlatformLayer, which
54 //    can be passed to the Scrolling Thread
55 // c) Remote scrolling UI process, where LayerRepresentation wraps just a PlatformLayerID.
56 class LayerRepresentation {
57 public:
58     enum Type {
59         EmptyRepresentation,
60         GraphicsLayerRepresentation,
61         PlatformLayerRepresentation,
62         PlatformLayerIDRepresentation
63     };
64
65     LayerRepresentation()
66         : m_graphicsLayer(nullptr)
67         , m_layerID(0)
68         , m_representation(EmptyRepresentation)
69     { }
70
71     LayerRepresentation(GraphicsLayer* graphicsLayer)
72         : m_graphicsLayer(graphicsLayer)
73         , m_layerID(graphicsLayer ? graphicsLayer->primaryLayerID() : 0)
74         , m_representation(GraphicsLayerRepresentation)
75     { }
76
77     LayerRepresentation(PlatformLayer* platformLayer)
78         : m_platformLayer(platformLayer)
79         , m_layerID(0)
80         , m_representation(PlatformLayerRepresentation)
81     {
82         retainPlatformLayer(platformLayer);
83     }
84
85     LayerRepresentation(GraphicsLayer::PlatformLayerID layerID)
86         : m_graphicsLayer(nullptr)
87         , m_layerID(layerID)
88         , m_representation(PlatformLayerIDRepresentation)
89     {
90     }
91
92     LayerRepresentation(const LayerRepresentation& other)
93         : m_platformLayer(other.m_platformLayer)
94         , m_layerID(other.m_layerID)
95         , m_representation(other.m_representation)
96     {
97         if (m_representation == PlatformLayerRepresentation)
98             retainPlatformLayer(m_platformLayer);
99     }
100
101     ~LayerRepresentation()
102     {
103         if (m_representation == PlatformLayerRepresentation)
104             releasePlatformLayer(m_platformLayer);
105     }
106
107     operator GraphicsLayer*() const
108     {
109         ASSERT(m_representation == GraphicsLayerRepresentation);
110         return m_graphicsLayer;
111     }
112
113     operator PlatformLayer*() const
114     {
115         ASSERT(m_representation == PlatformLayerRepresentation);
116         return m_platformLayer;
117     }
118     
119     GraphicsLayer::PlatformLayerID layerID() const
120     {
121         return m_layerID;
122     }
123
124     operator GraphicsLayer::PlatformLayerID() const
125     {
126         ASSERT(m_representation != PlatformLayerRepresentation);
127         return m_layerID;
128     }
129
130     LayerRepresentation& operator=(const LayerRepresentation& other)
131     {
132         m_platformLayer = other.m_platformLayer;
133         m_layerID = other.m_layerID;
134         m_representation = other.m_representation;
135
136         if (m_representation == PlatformLayerRepresentation)
137             retainPlatformLayer(m_platformLayer);
138
139         return *this;
140     }
141
142     bool operator==(const LayerRepresentation& other) const
143     {
144         if (m_representation != other.m_representation)
145             return false;
146         switch (m_representation) {
147         case EmptyRepresentation:
148             return true;
149         case GraphicsLayerRepresentation:
150             return m_graphicsLayer == other.m_graphicsLayer
151                 && m_layerID == other.m_layerID;
152         case PlatformLayerRepresentation:
153             return m_platformLayer == other.m_platformLayer;
154         case PlatformLayerIDRepresentation:
155             return m_layerID == other.m_layerID;
156         }
157         ASSERT_NOT_REACHED();
158         return true;
159     }
160     
161     LayerRepresentation toRepresentation(Type representation) const
162     {
163         switch (representation) {
164         case EmptyRepresentation:
165             return LayerRepresentation();
166         case GraphicsLayerRepresentation:
167             ASSERT(m_representation == GraphicsLayerRepresentation);
168             return *this;
169         case PlatformLayerRepresentation:
170             return m_graphicsLayer ? m_graphicsLayer->platformLayer() : nullptr;
171         case PlatformLayerIDRepresentation:
172             return LayerRepresentation(m_layerID);
173         }
174         return LayerRepresentation();
175     }
176
177     bool representsGraphicsLayer() const { return m_representation == GraphicsLayerRepresentation; }
178     bool representsPlatformLayerID() const { return m_representation == PlatformLayerIDRepresentation; }
179     
180 private:
181     WEBCORE_EXPORT void retainPlatformLayer(PlatformLayer*);
182     WEBCORE_EXPORT void releasePlatformLayer(PlatformLayer*);
183
184     union {
185         GraphicsLayer* m_graphicsLayer;
186         PlatformLayer *m_platformLayer;
187     };
188
189     GraphicsLayer::PlatformLayerID m_layerID;
190     Type m_representation;
191 };
192
193 class ScrollingStateNode : public RefCounted<ScrollingStateNode> {
194     WTF_MAKE_FAST_ALLOCATED;
195 public:
196     ScrollingStateNode(ScrollingNodeType, ScrollingStateTree&, ScrollingNodeID);
197     virtual ~ScrollingStateNode();
198     
199     ScrollingNodeType nodeType() const { return m_nodeType; }
200
201     bool isFixedNode() const { return m_nodeType == FixedNode; }
202     bool isStickyNode() const { return m_nodeType == StickyNode; }
203     bool isScrollingNode() const { return m_nodeType == FrameScrollingNode || m_nodeType == OverflowScrollingNode; }
204     bool isFrameScrollingNode() const { return m_nodeType == FrameScrollingNode; }
205     bool isOverflowScrollingNode() const { return m_nodeType == OverflowScrollingNode; }
206
207     virtual Ref<ScrollingStateNode> clone(ScrollingStateTree& adoptiveTree) = 0;
208     PassRefPtr<ScrollingStateNode> cloneAndReset(ScrollingStateTree& adoptiveTree);
209     void cloneAndResetChildren(ScrollingStateNode&, ScrollingStateTree& adoptiveTree);
210
211     enum {
212         ScrollLayer = 0,
213         NumStateNodeBits = 1
214     };
215     typedef unsigned ChangedProperties;
216
217     bool hasChangedProperties() const { return m_changedProperties; }
218     bool hasChangedProperty(unsigned propertyBit) const { return m_changedProperties & (1 << propertyBit); }
219     void resetChangedProperties() { m_changedProperties = 0; }
220     void setPropertyChanged(unsigned propertyBit);
221
222     ChangedProperties changedProperties() const { return m_changedProperties; }
223     void setChangedProperties(ChangedProperties changedProperties) { m_changedProperties = changedProperties; }
224     
225     virtual void syncLayerPositionForViewportRect(const LayoutRect& /*viewportRect*/) { }
226
227     const LayerRepresentation& layer() const { return m_layer; }
228     WEBCORE_EXPORT void setLayer(const LayerRepresentation&);
229
230     ScrollingStateTree& scrollingStateTree() const { return m_scrollingStateTree; }
231
232     ScrollingNodeID scrollingNodeID() const { return m_nodeID; }
233
234     ScrollingStateNode* parent() const { return m_parent; }
235     void setParent(ScrollingStateNode* parent) { m_parent = parent; }
236     ScrollingNodeID parentNodeID() const { return m_parent ? m_parent->scrollingNodeID() : 0; }
237
238     Vector<RefPtr<ScrollingStateNode>>* children() const { return m_children.get(); }
239
240     void appendChild(PassRefPtr<ScrollingStateNode>);
241
242     String scrollingStateTreeAsText() const;
243
244 protected:
245     ScrollingStateNode(const ScrollingStateNode&, ScrollingStateTree&);
246
247 private:
248     void dump(TextStream&, int indent, ScrollingStateTreeAsTextBehavior) const;
249
250     virtual void dumpProperties(TextStream&, int indent, ScrollingStateTreeAsTextBehavior) const = 0;
251
252     const ScrollingNodeType m_nodeType;
253     ScrollingNodeID m_nodeID;
254     ChangedProperties m_changedProperties;
255
256     ScrollingStateTree& m_scrollingStateTree;
257
258     ScrollingStateNode* m_parent;
259     std::unique_ptr<Vector<RefPtr<ScrollingStateNode>>> m_children;
260
261     LayerRepresentation m_layer;
262 };
263
264 } // namespace WebCore
265
266 #define SPECIALIZE_TYPE_TRAITS_SCROLLING_STATE_NODE(ToValueTypeName, predicate) \
267 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
268     static bool isType(const WebCore::ScrollingStateNode& node) { return node.predicate; } \
269 SPECIALIZE_TYPE_TRAITS_END()
270
271 #endif // ENABLE(ASYNC_SCROLLING) || USE(COORDINATED_GRAPHICS)
272
273 #endif // ScrollingStateNode_h