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