5f9b68fdbdcb3082d5493a45a585330dd44d8b79
[WebKit-https.git] / Source / WebKit / Shared / RemoteLayerTree / RemoteScrollingCoordinatorTransaction.cpp
1 /*
2  * Copyright (C) 2014-2015 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 #include "config.h"
27 #include "RemoteScrollingCoordinatorTransaction.h"
28
29 #include "ArgumentCoders.h"
30 #include "WebCoreArgumentCoders.h"
31 #include <WebCore/GraphicsLayer.h>
32 #include <WebCore/ScrollingStateFixedNode.h>
33 #include <WebCore/ScrollingStateFrameHostingNode.h>
34 #include <WebCore/ScrollingStateFrameScrollingNode.h>
35 #include <WebCore/ScrollingStateOverflowScrollProxyNode.h>
36 #include <WebCore/ScrollingStateOverflowScrollingNode.h>
37 #include <WebCore/ScrollingStatePositionedNode.h>
38 #include <WebCore/ScrollingStateStickyNode.h>
39 #include <WebCore/ScrollingStateTree.h>
40 #include <wtf/HashMap.h>
41 #include <wtf/text/CString.h>
42 #include <wtf/text/TextStream.h>
43
44 #if ENABLE(ASYNC_SCROLLING)
45
46 namespace IPC {
47 using namespace WebCore;
48
49 template<> struct ArgumentCoder<ScrollingStateNode> {
50     static void encode(Encoder&, const ScrollingStateNode&);
51     static bool decode(Decoder&, ScrollingStateNode&);
52 };
53
54 template<> struct ArgumentCoder<ScrollingStateScrollingNode> {
55     static void encode(Encoder&, const ScrollingStateScrollingNode&);
56     static bool decode(Decoder&, ScrollingStateScrollingNode&);
57 };
58
59 template<> struct ArgumentCoder<ScrollingStateFrameHostingNode> {
60     static void encode(Encoder&, const ScrollingStateFrameHostingNode&);
61     static bool decode(Decoder&, ScrollingStateFrameHostingNode&);
62 };
63
64 template<> struct ArgumentCoder<ScrollingStateFrameScrollingNode> {
65     static void encode(Encoder&, const ScrollingStateFrameScrollingNode&);
66     static bool decode(Decoder&, ScrollingStateFrameScrollingNode&);
67 };
68
69 template<> struct ArgumentCoder<ScrollingStateOverflowScrollingNode> {
70     static void encode(Encoder&, const ScrollingStateOverflowScrollingNode&);
71     static bool decode(Decoder&, ScrollingStateOverflowScrollingNode&);
72 };
73
74 template<> struct ArgumentCoder<ScrollingStateOverflowScrollProxyNode> {
75     static void encode(Encoder&, const ScrollingStateOverflowScrollProxyNode&);
76     static bool decode(Decoder&, ScrollingStateOverflowScrollProxyNode&);
77 };
78
79 template<> struct ArgumentCoder<ScrollingStateFixedNode> {
80     static void encode(Encoder&, const ScrollingStateFixedNode&);
81     static bool decode(Decoder&, ScrollingStateFixedNode&);
82 };
83
84 template<> struct ArgumentCoder<ScrollingStateStickyNode> {
85     static void encode(Encoder&, const ScrollingStateStickyNode&);
86     static bool decode(Decoder&, ScrollingStateStickyNode&);
87 };
88
89 template<> struct ArgumentCoder<ScrollingStatePositionedNode> {
90     static void encode(Encoder&, const ScrollingStatePositionedNode&);
91     static bool decode(Decoder&, ScrollingStatePositionedNode&);
92 };
93
94 } // namespace IPC
95
96 using namespace IPC;
97
98 void ArgumentCoder<ScrollingStateNode>::encode(Encoder& encoder, const ScrollingStateNode& node)
99 {
100     encoder.encodeEnum(node.nodeType());
101     encoder << node.scrollingNodeID();
102     encoder << node.parentNodeID();
103     encoder << node.changedProperties();
104     
105     if (node.hasChangedProperty(ScrollingStateNode::Layer))
106         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.layer());
107 }
108
109 bool ArgumentCoder<ScrollingStateNode>::decode(Decoder& decoder, ScrollingStateNode& node)
110 {
111     // nodeType, scrollingNodeID and parentNodeID have already been decoded by the caller in order to create the node.
112     ScrollingStateNode::ChangedProperties changedProperties;
113     if (!decoder.decode(changedProperties))
114         return false;
115
116     node.setChangedProperties(changedProperties);
117     if (node.hasChangedProperty(ScrollingStateNode::Layer)) {
118         GraphicsLayer::PlatformLayerID layerID;
119         if (!decoder.decode(layerID))
120             return false;
121         node.setLayer(layerID);
122     }
123
124     return true;
125 }
126
127 #define SCROLLING_NODE_ENCODE(property, getter) \
128     if (node.hasChangedProperty(property)) \
129         encoder << node.getter();
130
131 #define SCROLLING_NODE_ENCODE_ENUM(property, getter) \
132     if (node.hasChangedProperty(property)) \
133         encoder.encodeEnum(node.getter());
134
135 void ArgumentCoder<ScrollingStateScrollingNode>::encode(Encoder& encoder, const ScrollingStateScrollingNode& node)
136 {
137     encoder << static_cast<const ScrollingStateNode&>(node);
138     
139     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaSize, scrollableAreaSize)
140     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::TotalContentsSize, totalContentsSize)
141     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ReachableContentsSize, reachableContentsSize)
142     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollPosition, scrollPosition)
143     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollOrigin, scrollOrigin)
144 #if ENABLE(CSS_SCROLL_SNAP)
145     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, horizontalSnapOffsets)
146     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsets, verticalSnapOffsets)
147     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsetRanges, horizontalSnapOffsetRanges)
148     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsetRanges, verticalSnapOffsetRanges)
149     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, currentHorizontalSnapPointIndex)
150     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, currentVerticalSnapPointIndex)
151 #endif
152     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
153     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
154     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPositionRepresentsProgrammaticScroll)
155
156     if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer))
157         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrollContainerLayer());
158
159     if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
160         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer());
161
162     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer))
163         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.horizontalScrollbarLayer());
164
165     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer))
166         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.verticalScrollbarLayer());
167 }
168
169 void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, const ScrollingStateFrameScrollingNode& node)
170 {
171     encoder << static_cast<const ScrollingStateScrollingNode&>(node);
172
173     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, frameScaleFactor)
174     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, eventTrackingRegions)
175     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, synchronousScrollingReasons)
176     SCROLLING_NODE_ENCODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, scrollBehaviorForFixedElements)
177     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::HeaderHeight, headerHeight)
178     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FooterHeight, footerHeight)
179     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::TopContentInset, topContentInset)
180     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, fixedElementsLayoutRelativeToFrame)
181     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::VisualViewportIsSmallerThanLayoutViewport, visualViewportIsSmallerThanLayoutViewport)
182     // AsyncFrameOrOverflowScrollingEnabled is not relevant for UI-side compositing.
183     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::LayoutViewport, layoutViewport)
184     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MinLayoutViewportOrigin, minLayoutViewportOrigin)
185     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MaxLayoutViewportOrigin, maxLayoutViewportOrigin)
186
187     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer))
188         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.counterScrollingLayer());
189
190     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
191         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer());
192
193     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
194         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer());
195
196     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::RootContentsLayer))
197         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.rootContentsLayer());
198 }
199
200 void ArgumentCoder<ScrollingStateFrameHostingNode>::encode(Encoder& encoder, const ScrollingStateFrameHostingNode& node)
201 {
202     encoder << static_cast<const ScrollingStateNode&>(node);
203     // ParentRelativeScrollableRect isn't used so we don't encode it.
204 }
205
206 void ArgumentCoder<ScrollingStateOverflowScrollingNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollingNode& node)
207 {
208     encoder << static_cast<const ScrollingStateScrollingNode&>(node);
209 }
210
211 void ArgumentCoder<ScrollingStateOverflowScrollProxyNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollProxyNode& node)
212 {
213     encoder << static_cast<const ScrollingStateNode&>(node);
214     SCROLLING_NODE_ENCODE(ScrollingStateOverflowScrollProxyNode::OverflowScrollingNode, overflowScrollingNode)
215 }
216
217 #define SCROLLING_NODE_DECODE(property, type, setter) \
218     if (node.hasChangedProperty(property)) { \
219         type decodedValue; \
220         if (!decoder.decode(decodedValue)) \
221             return false; \
222         node.setter(decodedValue); \
223     }
224
225 #define SCROLLING_NODE_DECODE_ENUM(property, type, setter) \
226     if (node.hasChangedProperty(property)) { \
227         type decodedValue; \
228         if (!decoder.decodeEnum(decodedValue)) \
229             return false; \
230         node.setter(decodedValue); \
231     }
232
233 bool ArgumentCoder<ScrollingStateScrollingNode>::decode(Decoder& decoder, ScrollingStateScrollingNode& node)
234 {
235     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
236         return false;
237
238     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaSize, FloatSize, setScrollableAreaSize);
239     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::TotalContentsSize, FloatSize, setTotalContentsSize);
240     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ReachableContentsSize, FloatSize, setReachableContentsSize);
241     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollPosition, FloatPoint, setScrollPosition);
242     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollOrigin, IntPoint, setScrollOrigin);
243 #if ENABLE(CSS_SCROLL_SNAP)
244     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, Vector<float>, setHorizontalSnapOffsets);
245     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsets, Vector<float>, setVerticalSnapOffsets);
246     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsetRanges, Vector<ScrollOffsetRange<float>>, setHorizontalSnapOffsetRanges)
247     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsetRanges, Vector<ScrollOffsetRange<float>>, setVerticalSnapOffsetRanges)
248     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, unsigned, setCurrentHorizontalSnapPointIndex);
249     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, unsigned, setCurrentVerticalSnapPointIndex);
250 #endif
251     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
252     
253     if (node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
254         FloatPoint scrollPosition;
255         if (!decoder.decode(scrollPosition))
256             return false;
257
258         bool representsProgrammaticScroll;
259         if (!decoder.decode(representsProgrammaticScroll))
260             return false;
261
262         node.setRequestedScrollPosition(scrollPosition, representsProgrammaticScroll);
263     }
264
265     if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer)) {
266         GraphicsLayer::PlatformLayerID layerID;
267         if (!decoder.decode(layerID))
268             return false;
269         node.setScrollContainerLayer(layerID);
270     }
271
272     if (node.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer)) {
273         GraphicsLayer::PlatformLayerID layerID;
274         if (!decoder.decode(layerID))
275             return false;
276         node.setScrolledContentsLayer(layerID);
277     }
278
279     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::HorizontalScrollbarLayer)) {
280         GraphicsLayer::PlatformLayerID layerID;
281         if (!decoder.decode(layerID))
282             return false;
283         node.setHorizontalScrollbarLayer(layerID);
284     }
285
286     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::VerticalScrollbarLayer)) {
287         GraphicsLayer::PlatformLayerID layerID;
288         if (!decoder.decode(layerID))
289             return false;
290         node.setVerticalScrollbarLayer(layerID);
291     }
292
293     return true;
294 }
295
296 bool ArgumentCoder<ScrollingStateFrameScrollingNode>::decode(Decoder& decoder, ScrollingStateFrameScrollingNode& node)
297 {
298     if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
299         return false;
300
301     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, float, setFrameScaleFactor);
302     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, EventTrackingRegions, setEventTrackingRegions);
303     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, SynchronousScrollingReasons, setSynchronousScrollingReasons);
304     SCROLLING_NODE_DECODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, ScrollBehaviorForFixedElements, setScrollBehaviorForFixedElements);
305
306     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::HeaderHeight, int, setHeaderHeight);
307     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FooterHeight, int, setFooterHeight);
308     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::TopContentInset, float, setTopContentInset);
309     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, bool, setFixedElementsLayoutRelativeToFrame);
310     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::VisualViewportIsSmallerThanLayoutViewport, bool, setVisualViewportIsSmallerThanLayoutViewport);
311     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::LayoutViewport, FloatRect, setLayoutViewport)
312     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::MinLayoutViewportOrigin, FloatPoint, setMinLayoutViewportOrigin)
313     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::MaxLayoutViewportOrigin, FloatPoint, setMaxLayoutViewportOrigin)
314
315     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) {
316         GraphicsLayer::PlatformLayerID layerID;
317         if (!decoder.decode(layerID))
318             return false;
319         node.setCounterScrollingLayer(layerID);
320     }
321
322     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) {
323         GraphicsLayer::PlatformLayerID layerID;
324         if (!decoder.decode(layerID))
325             return false;
326         node.setInsetClipLayer(layerID);
327     }
328
329     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) {
330         GraphicsLayer::PlatformLayerID layerID;
331         if (!decoder.decode(layerID))
332             return false;
333         node.setContentShadowLayer(layerID);
334     }
335
336     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::RootContentsLayer)) {
337         GraphicsLayer::PlatformLayerID layerID;
338         if (!decoder.decode(layerID))
339             return false;
340         node.setRootContentsLayer(layerID);
341     }
342
343     return true;
344 }
345
346 bool ArgumentCoder<ScrollingStateFrameHostingNode>::decode(Decoder& decoder, ScrollingStateFrameHostingNode& node)
347 {
348     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
349         return false;
350
351     return true;
352 }
353
354 bool ArgumentCoder<ScrollingStateOverflowScrollingNode>::decode(Decoder& decoder, ScrollingStateOverflowScrollingNode& node)
355 {
356     if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
357         return false;
358
359     return true;
360 }
361
362 bool ArgumentCoder<ScrollingStateOverflowScrollProxyNode>::decode(Decoder& decoder, ScrollingStateOverflowScrollProxyNode& node)
363 {
364     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
365         return false;
366
367     SCROLLING_NODE_DECODE(ScrollingStateOverflowScrollProxyNode::OverflowScrollingNode, ScrollingNodeID, setOverflowScrollingNode);
368     return true;
369 }
370
371 void ArgumentCoder<ScrollingStateFixedNode>::encode(Encoder& encoder, const ScrollingStateFixedNode& node)
372 {
373     encoder << static_cast<const ScrollingStateNode&>(node);
374     
375     if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
376         encoder << node.viewportConstraints();
377 }
378
379 bool ArgumentCoder<ScrollingStateFixedNode>::decode(Decoder& decoder, ScrollingStateFixedNode& node)
380 {
381     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
382         return false;
383
384     if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints)) {
385         FixedPositionViewportConstraints decodedValue;
386         if (!decoder.decode(decodedValue))
387             return false;
388         node.updateConstraints(decodedValue);
389     }
390
391     return true;
392 }
393
394 void ArgumentCoder<ScrollingStateStickyNode>::encode(Encoder& encoder, const ScrollingStateStickyNode& node)
395 {
396     encoder << static_cast<const ScrollingStateNode&>(node);
397     
398     if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints))
399         encoder << node.viewportConstraints();
400 }
401
402 bool ArgumentCoder<ScrollingStateStickyNode>::decode(Decoder& decoder, ScrollingStateStickyNode& node)
403 {
404     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
405         return false;
406
407     if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints)) {
408         StickyPositionViewportConstraints decodedValue;
409         if (!decoder.decode(decodedValue))
410             return false;
411         node.updateConstraints(decodedValue);
412     }
413
414     return true;
415 }
416
417 void ArgumentCoder<ScrollingStatePositionedNode>::encode(Encoder& encoder, const ScrollingStatePositionedNode& node)
418 {
419     encoder << static_cast<const ScrollingStateNode&>(node);
420
421     if (node.hasChangedProperty(ScrollingStatePositionedNode::RelatedOverflowScrollingNodes))
422         encoder << node.relatedOverflowScrollingNodes();
423
424     if (node.hasChangedProperty(ScrollingStatePositionedNode::LayoutConstraintData))
425         encoder << node.layoutConstraints();
426 }
427
428 bool ArgumentCoder<ScrollingStatePositionedNode>::decode(Decoder& decoder, ScrollingStatePositionedNode& node)
429 {
430     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
431         return false;
432
433     if (node.hasChangedProperty(ScrollingStatePositionedNode::RelatedOverflowScrollingNodes)) {
434         Vector<ScrollingNodeID> decodedValue;
435         if (!decoder.decode(decodedValue))
436             return false;
437         node.setRelatedOverflowScrollingNodes(WTFMove(decodedValue));
438     }
439
440     if (node.hasChangedProperty(ScrollingStatePositionedNode::LayoutConstraintData)) {
441         AbsolutePositionConstraints decodedValue;
442         if (!decoder.decode(decodedValue))
443             return false;
444         node.updateConstraints(decodedValue);
445     }
446
447     return true;
448 }
449
450 namespace WebKit {
451
452 static void encodeNodeAndDescendants(IPC::Encoder& encoder, const ScrollingStateNode& stateNode, int& encodedNodeCount)
453 {
454     ++encodedNodeCount;
455
456     switch (stateNode.nodeType()) {
457     case ScrollingNodeType::MainFrame:
458     case ScrollingNodeType::Subframe:
459         encoder << downcast<ScrollingStateFrameScrollingNode>(stateNode);
460         break;
461     case ScrollingNodeType::FrameHosting:
462         encoder << downcast<ScrollingStateFrameHostingNode>(stateNode);
463         break;
464     case ScrollingNodeType::Overflow:
465         encoder << downcast<ScrollingStateOverflowScrollingNode>(stateNode);
466         break;
467     case ScrollingNodeType::OverflowProxy:
468         encoder << downcast<ScrollingStateOverflowScrollProxyNode>(stateNode);
469         break;
470     case ScrollingNodeType::Fixed:
471         encoder << downcast<ScrollingStateFixedNode>(stateNode);
472         break;
473     case ScrollingNodeType::Sticky:
474         encoder << downcast<ScrollingStateStickyNode>(stateNode);
475         break;
476     case ScrollingNodeType::Positioned:
477         encoder << downcast<ScrollingStatePositionedNode>(stateNode);
478         break;
479     }
480
481     if (!stateNode.children())
482         return;
483
484     for (const auto& child : *stateNode.children())
485         encodeNodeAndDescendants(encoder, *child.get(), encodedNodeCount);
486 }
487
488 void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder& encoder) const
489 {
490     int numNodes = m_scrollingStateTree ? m_scrollingStateTree->nodeCount() : 0;
491     encoder << numNodes;
492     
493     bool hasNewRootNode = m_scrollingStateTree ? m_scrollingStateTree->hasNewRootStateNode() : false;
494     encoder << hasNewRootNode;
495
496     if (m_scrollingStateTree) {
497         encoder << m_scrollingStateTree->hasChangedProperties();
498
499         int numNodesEncoded = 0;
500         if (const ScrollingStateNode* rootNode = m_scrollingStateTree->rootStateNode())
501             encodeNodeAndDescendants(encoder, *rootNode, numNodesEncoded);
502
503         ASSERT_UNUSED(numNodesEncoded, numNodesEncoded == numNodes);
504     } else
505         encoder << Vector<ScrollingNodeID>();
506 }
507
508 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
509 {
510     return transaction.decode(decoder);
511 }
512
513 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder)
514 {
515     int numNodes;
516     if (!decoder.decode(numNodes))
517         return false;
518
519     bool hasNewRootNode;
520     if (!decoder.decode(hasNewRootNode))
521         return false;
522     
523     m_scrollingStateTree = std::make_unique<ScrollingStateTree>();
524
525     bool hasChangedProperties;
526     if (!decoder.decode(hasChangedProperties))
527         return false;
528
529     m_scrollingStateTree->setHasChangedProperties(hasChangedProperties);
530
531     for (int i = 0; i < numNodes; ++i) {
532         ScrollingNodeType nodeType;
533         if (!decoder.decodeEnum(nodeType))
534             return false;
535
536         ScrollingNodeID nodeID;
537         if (!decoder.decode(nodeID))
538             return false;
539
540         ScrollingNodeID parentNodeID;
541         if (!decoder.decode(parentNodeID))
542             return false;
543
544         m_scrollingStateTree->insertNode(nodeType, nodeID, parentNodeID, notFound);
545         ScrollingStateNode* newNode = m_scrollingStateTree->stateNodeForID(nodeID);
546         ASSERT(newNode);
547         ASSERT(!parentNodeID || newNode->parent());
548         
549         switch (nodeType) {
550         case ScrollingNodeType::MainFrame:
551         case ScrollingNodeType::Subframe:
552             if (!decoder.decode(downcast<ScrollingStateFrameScrollingNode>(*newNode)))
553                 return false;
554             break;
555         case ScrollingNodeType::FrameHosting:
556             if (!decoder.decode(downcast<ScrollingStateFrameHostingNode>(*newNode)))
557                 return false;
558             break;
559         case ScrollingNodeType::Overflow:
560             if (!decoder.decode(downcast<ScrollingStateOverflowScrollingNode>(*newNode)))
561                 return false;
562             break;
563         case ScrollingNodeType::OverflowProxy:
564             if (!decoder.decode(downcast<ScrollingStateOverflowScrollProxyNode>(*newNode)))
565                 return false;
566             break;
567         case ScrollingNodeType::Fixed:
568             if (!decoder.decode(downcast<ScrollingStateFixedNode>(*newNode)))
569                 return false;
570             break;
571         case ScrollingNodeType::Sticky:
572             if (!decoder.decode(downcast<ScrollingStateStickyNode>(*newNode)))
573                 return false;
574             break;
575         case ScrollingNodeType::Positioned:
576             if (!decoder.decode(downcast<ScrollingStatePositionedNode>(*newNode)))
577                 return false;
578             break;
579         }
580     }
581
582     m_scrollingStateTree->setHasNewRootStateNode(hasNewRootNode);
583
584     return true;
585 }
586
587 #if !defined(NDEBUG) || !LOG_DISABLED
588
589 static void dump(TextStream& ts, const ScrollingStateScrollingNode& node, bool changedPropertiesOnly)
590 {
591     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaSize))
592         ts.dumpProperty("scrollable-area-size", node.scrollableAreaSize());
593
594     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize))
595         ts.dumpProperty("total-contents-size", node.totalContentsSize());
596
597     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize))
598         ts.dumpProperty("reachable-contents-size", node.reachableContentsSize());
599
600     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition))
601         ts.dumpProperty("scroll-position", node.scrollPosition());
602
603     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
604         ts.dumpProperty("scroll-origin", node.scrollOrigin());
605
606     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
607         ts.dumpProperty("requested-scroll-position", node.requestedScrollPosition());
608         ts.dumpProperty("requested-scroll-position-is-programatic", node.requestedScrollPositionRepresentsProgrammaticScroll());
609     }
610
611     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer))
612         ts.dumpProperty("scroll-container-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrollContainerLayer()));
613
614     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
615         ts.dumpProperty("scrolled-contents-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer()));
616 }
617
618 static void dump(TextStream& ts, const ScrollingStateFrameHostingNode& node, bool changedPropertiesOnly)
619 {
620 }
621
622 static void dump(TextStream& ts, const ScrollingStateFrameScrollingNode& node, bool changedPropertiesOnly)
623 {
624     dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
625     
626     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
627         ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
628
629     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::EventTrackingRegion)) {
630         {
631             TextStream::GroupScope group(ts);
632             ts << "asynchronous-event-tracking-region";
633             for (auto rect : node.eventTrackingRegions().asynchronousDispatchRegion.rects()) {
634                 ts << "\n";
635                 ts.writeIndent();
636                 ts << rect;
637             }
638         }
639         for (const auto& synchronousEventRegion : node.eventTrackingRegions().eventSpecificSynchronousDispatchRegions) {
640             TextStream::GroupScope group(ts);
641             ts << "synchronous-event-tracking-region for event " << synchronousEventRegion.key;
642
643             for (auto rect : synchronousEventRegion.value.rects()) {
644                 ts << "\n";
645                 ts.writeIndent();
646                 ts << rect;
647             }
648         }
649     }
650
651     // FIXME: dump synchronousScrollingReasons
652     // FIXME: dump scrollableAreaParameters
653     // FIXME: dump scrollBehaviorForFixedElements
654
655     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderHeight))
656         ts.dumpProperty("header-height", node.headerHeight());
657
658     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterHeight))
659         ts.dumpProperty("footer-height", node.footerHeight());
660
661     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::TopContentInset))
662         ts.dumpProperty("top-content-inset", node.topContentInset());
663
664     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
665         ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
666
667     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
668         ts.dumpProperty("clip-inset-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer()));
669
670     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
671         ts.dumpProperty("content-shadow-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer()));
672
673     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer))
674         ts.dumpProperty("header-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.headerLayer()));
675
676     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer))
677         ts.dumpProperty("footer-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.footerLayer()));
678 }
679     
680 static void dump(TextStream& ts, const ScrollingStateOverflowScrollingNode& node, bool changedPropertiesOnly)
681 {
682     dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
683 }
684
685 static void dump(TextStream& ts, const ScrollingStateOverflowScrollProxyNode& node, bool changedPropertiesOnly)
686 {
687     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateOverflowScrollProxyNode::OverflowScrollingNode))
688         ts.dumpProperty("overflow-scrolling-node", node.overflowScrollingNode());
689 }
690
691 static void dump(TextStream& ts, const ScrollingStateFixedNode& node, bool changedPropertiesOnly)
692 {
693     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
694         ts << node.viewportConstraints();
695 }
696
697 static void dump(TextStream& ts, const ScrollingStateStickyNode& node, bool changedPropertiesOnly)
698 {
699     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
700         ts << node.viewportConstraints();
701 }
702
703 static void dump(TextStream& ts, const ScrollingStatePositionedNode& node, bool changedPropertiesOnly)
704 {
705     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStatePositionedNode::RelatedOverflowScrollingNodes))
706         ts << node.relatedOverflowScrollingNodes();
707
708     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStatePositionedNode::LayoutConstraintData))
709         ts << node.layoutConstraints();
710 }
711
712 static void dump(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
713 {
714     ts.dumpProperty("type", node.nodeType());
715
716     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateNode::Layer))
717         ts.dumpProperty("layer", static_cast<GraphicsLayer::PlatformLayerID>(node.layer()));
718     
719     switch (node.nodeType()) {
720     case ScrollingNodeType::MainFrame:
721     case ScrollingNodeType::Subframe:
722         dump(ts, downcast<ScrollingStateFrameScrollingNode>(node), changedPropertiesOnly);
723         break;
724     case ScrollingNodeType::FrameHosting:
725         dump(ts, downcast<ScrollingStateFrameHostingNode>(node), changedPropertiesOnly);
726         break;
727     case ScrollingNodeType::Overflow:
728         dump(ts, downcast<ScrollingStateOverflowScrollingNode>(node), changedPropertiesOnly);
729         break;
730     case ScrollingNodeType::OverflowProxy:
731         dump(ts, downcast<ScrollingStateOverflowScrollProxyNode>(node), changedPropertiesOnly);
732         break;
733     case ScrollingNodeType::Fixed:
734         dump(ts, downcast<ScrollingStateFixedNode>(node), changedPropertiesOnly);
735         break;
736     case ScrollingNodeType::Sticky:
737         dump(ts, downcast<ScrollingStateStickyNode>(node), changedPropertiesOnly);
738         break;
739     case ScrollingNodeType::Positioned:
740         dump(ts, downcast<ScrollingStatePositionedNode>(node), changedPropertiesOnly);
741         break;
742     }
743 }
744
745 static void recursiveDumpNodes(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
746 {
747     TextStream::GroupScope group(ts);
748     ts << "node " << node.scrollingNodeID();
749     dump(ts, node, changedPropertiesOnly);
750
751     if (node.children()) {
752         TextStream::GroupScope group(ts);
753         ts << "children";
754
755         for (auto& childNode : *node.children())
756             recursiveDumpNodes(ts, *childNode, changedPropertiesOnly);
757     }
758 }
759
760 static void dump(TextStream& ts, const ScrollingStateTree& stateTree, bool changedPropertiesOnly)
761 {
762     ts.dumpProperty("has changed properties", stateTree.hasChangedProperties());
763     ts.dumpProperty("has new root node", stateTree.hasNewRootStateNode());
764
765     if (stateTree.rootStateNode())
766         recursiveDumpNodes(ts, *stateTree.rootStateNode(), changedPropertiesOnly);
767 }
768
769 WTF::CString RemoteScrollingCoordinatorTransaction::description() const
770 {
771     TextStream ts;
772
773     ts.startGroup();
774     ts << "scrolling state tree";
775
776     if (m_scrollingStateTree) {
777         if (!m_scrollingStateTree->hasChangedProperties())
778             ts << " - no changes";
779         else
780             WebKit::dump(ts, *m_scrollingStateTree.get(), true);
781     } else
782         ts << " - none";
783
784     ts.endGroup();
785
786     return ts.release().utf8();
787 }
788
789 void RemoteScrollingCoordinatorTransaction::dump() const
790 {
791     fprintf(stderr, "%s", description().data());
792 }
793 #endif
794
795 } // namespace WebKit
796
797 #else // !ENABLE(ASYNC_SCROLLING)
798
799 namespace WebKit {
800
801 void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder&) const
802 {
803 }
804
805 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
806 {
807     return true;
808 }
809
810 } // namespace WebKit
811
812 #endif // ENABLE(ASYNC_SCROLLING)