bdaffab570dc8c98ac25100e52727d566ccaa5f1
[WebKit-https.git] / Source / WebKit2 / Shared / Scrolling / 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/ScrollingStateFrameScrollingNode.h>
34 #include <WebCore/ScrollingStateOverflowScrollingNode.h>
35 #include <WebCore/ScrollingStateStickyNode.h>
36 #include <WebCore/ScrollingStateTree.h>
37 #include <WebCore/TextStream.h>
38 #include <wtf/HashMap.h>
39 #include <wtf/text/CString.h>
40
41 using namespace WebCore;
42
43 #if ENABLE(ASYNC_SCROLLING)
44
45 namespace IPC {
46
47 template<> struct ArgumentCoder<ScrollingStateNode> {
48     static void encode(Encoder&, const ScrollingStateNode&);
49     static bool decode(Decoder&, ScrollingStateNode&);
50 };
51
52 template<> struct ArgumentCoder<ScrollingStateScrollingNode> {
53     static void encode(Encoder&, const ScrollingStateScrollingNode&);
54     static bool decode(Decoder&, ScrollingStateScrollingNode&);
55 };
56     
57 template<> struct ArgumentCoder<ScrollingStateFrameScrollingNode> {
58     static void encode(Encoder&, const ScrollingStateFrameScrollingNode&);
59     static bool decode(Decoder&, ScrollingStateFrameScrollingNode&);
60 };
61     
62 template<> struct ArgumentCoder<ScrollingStateOverflowScrollingNode> {
63     static void encode(Encoder&, const ScrollingStateOverflowScrollingNode&);
64     static bool decode(Decoder&, ScrollingStateOverflowScrollingNode&);
65 };
66     
67 template<> struct ArgumentCoder<ScrollingStateFixedNode> {
68     static void encode(Encoder&, const ScrollingStateFixedNode&);
69     static bool decode(Decoder&, ScrollingStateFixedNode&);
70 };
71
72 template<> struct ArgumentCoder<ScrollingStateStickyNode> {
73     static void encode(Encoder&, const ScrollingStateStickyNode&);
74     static bool decode(Decoder&, ScrollingStateStickyNode&);
75 };
76
77 } // namespace IPC
78
79 using namespace IPC;
80
81 void ArgumentCoder<ScrollingStateNode>::encode(Encoder& encoder, const ScrollingStateNode& node)
82 {
83     encoder.encodeEnum(node.nodeType());
84     encoder << node.scrollingNodeID();
85     encoder << node.parentNodeID();
86     encoder << node.changedProperties();
87     
88     if (node.hasChangedProperty(ScrollingStateNode::ScrollLayer))
89         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.layer());
90 }
91
92 bool ArgumentCoder<ScrollingStateNode>::decode(Decoder& decoder, ScrollingStateNode& node)
93 {
94     // nodeType, scrollingNodeID and parentNodeID have already been decoded by the caller in order to create the node.
95     ScrollingStateNode::ChangedProperties changedProperties;
96     if (!decoder.decode(changedProperties))
97         return false;
98
99     node.setChangedProperties(changedProperties);
100     if (node.hasChangedProperty(ScrollingStateNode::ScrollLayer)) {
101         GraphicsLayer::PlatformLayerID layerID;
102         if (!decoder.decode(layerID))
103             return false;
104         node.setLayer(layerID);
105     }
106
107     return true;
108 }
109
110 #define SCROLLING_NODE_ENCODE(property, getter) \
111     if (node.hasChangedProperty(property)) \
112         encoder << node.getter();
113
114 #define SCROLLING_NODE_ENCODE_ENUM(property, getter) \
115     if (node.hasChangedProperty(property)) \
116         encoder.encodeEnum(node.getter());
117
118 void ArgumentCoder<ScrollingStateScrollingNode>::encode(Encoder& encoder, const ScrollingStateScrollingNode& node)
119 {
120     encoder << static_cast<const ScrollingStateNode&>(node);
121     
122     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaSize, scrollableAreaSize)
123     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::TotalContentsSize, totalContentsSize)
124     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ReachableContentsSize, reachableContentsSize)
125     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollPosition, scrollPosition)
126     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollOrigin, scrollOrigin)
127 #if ENABLE(CSS_SCROLL_SNAP)
128     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, horizontalSnapOffsets)
129     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsets, verticalSnapOffsets)
130     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, currentHorizontalSnapPointIndex)
131     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, currentVerticalSnapPointIndex)
132 #endif
133     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
134     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
135     SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPositionRepresentsProgrammaticScroll)
136 }
137
138 void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, const ScrollingStateFrameScrollingNode& node)
139 {
140     encoder << static_cast<const ScrollingStateScrollingNode&>(node);
141     
142     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, frameScaleFactor)
143     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, eventTrackingRegions)
144     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, synchronousScrollingReasons)
145     SCROLLING_NODE_ENCODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, scrollBehaviorForFixedElements)
146     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::HeaderHeight, headerHeight)
147     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FooterHeight, footerHeight)
148     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::TopContentInset, topContentInset)
149     SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, fixedElementsLayoutRelativeToFrame)
150
151     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer))
152         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer());
153
154     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer))
155         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.counterScrollingLayer());
156
157     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
158         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer());
159
160     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
161         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer());
162 }
163
164 void ArgumentCoder<ScrollingStateOverflowScrollingNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollingNode& node)
165 {
166     encoder << static_cast<const ScrollingStateScrollingNode&>(node);
167     
168     if (node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer))
169         encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer());
170 }
171
172 #define SCROLLING_NODE_DECODE(property, type, setter) \
173     if (node.hasChangedProperty(property)) { \
174         type decodedValue; \
175         if (!decoder.decode(decodedValue)) \
176             return false; \
177         node.setter(decodedValue); \
178     }
179
180 #define SCROLLING_NODE_DECODE_ENUM(property, type, setter) \
181     if (node.hasChangedProperty(property)) { \
182         type decodedValue; \
183         if (!decoder.decodeEnum(decodedValue)) \
184             return false; \
185         node.setter(decodedValue); \
186     }
187
188 bool ArgumentCoder<ScrollingStateScrollingNode>::decode(Decoder& decoder, ScrollingStateScrollingNode& node)
189 {
190     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
191         return false;
192
193     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaSize, FloatSize, setScrollableAreaSize);
194     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::TotalContentsSize, FloatSize, setTotalContentsSize);
195     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ReachableContentsSize, FloatSize, setReachableContentsSize);
196     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollPosition, FloatPoint, setScrollPosition);
197     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollOrigin, IntPoint, setScrollOrigin);
198 #if ENABLE(CSS_SCROLL_SNAP)
199     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, Vector<float>, setHorizontalSnapOffsets);
200     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsets, Vector<float>, setVerticalSnapOffsets);
201     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, unsigned, setCurrentHorizontalSnapPointIndex);
202     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, unsigned, setCurrentVerticalSnapPointIndex);
203 #endif
204     SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
205     
206     if (node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
207         FloatPoint scrollPosition;
208         if (!decoder.decode(scrollPosition))
209             return false;
210
211         bool representsProgrammaticScroll;
212         if (!decoder.decode(representsProgrammaticScroll))
213             return false;
214
215         node.setRequestedScrollPosition(scrollPosition, representsProgrammaticScroll);
216     }
217
218     return true;
219 }
220
221 bool ArgumentCoder<ScrollingStateFrameScrollingNode>::decode(Decoder& decoder, ScrollingStateFrameScrollingNode& node)
222 {
223     if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
224         return false;
225
226     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, float, setFrameScaleFactor);
227     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, EventTrackingRegions, setEventTrackingRegions);
228     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, SynchronousScrollingReasons, setSynchronousScrollingReasons);
229     SCROLLING_NODE_DECODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, ScrollBehaviorForFixedElements, setScrollBehaviorForFixedElements);
230
231     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::HeaderHeight, int, setHeaderHeight);
232     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FooterHeight, int, setFooterHeight);
233     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::TopContentInset, float, setTopContentInset);
234     SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, bool, setFixedElementsLayoutRelativeToFrame);
235
236     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer)) {
237         GraphicsLayer::PlatformLayerID layerID;
238         if (!decoder.decode(layerID))
239             return false;
240         node.setScrolledContentsLayer(layerID);
241     }
242
243     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) {
244         GraphicsLayer::PlatformLayerID layerID;
245         if (!decoder.decode(layerID))
246             return false;
247         node.setCounterScrollingLayer(layerID);
248     }
249
250     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) {
251         GraphicsLayer::PlatformLayerID layerID;
252         if (!decoder.decode(layerID))
253             return false;
254         node.setInsetClipLayer(layerID);
255     }
256
257     if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) {
258         GraphicsLayer::PlatformLayerID layerID;
259         if (!decoder.decode(layerID))
260             return false;
261         node.setContentShadowLayer(layerID);
262     }
263
264     return true;
265 }
266
267 bool ArgumentCoder<ScrollingStateOverflowScrollingNode>::decode(Decoder& decoder, ScrollingStateOverflowScrollingNode& node)
268 {
269     if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
270         return false;
271
272     if (node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer)) {
273         GraphicsLayer::PlatformLayerID layerID;
274         if (!decoder.decode(layerID))
275             return false;
276         node.setScrolledContentsLayer(layerID);
277     }
278
279     return true;
280 }
281
282 void ArgumentCoder<ScrollingStateFixedNode>::encode(Encoder& encoder, const ScrollingStateFixedNode& node)
283 {
284     encoder << static_cast<const ScrollingStateNode&>(node);
285     
286     if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
287         encoder << node.viewportConstraints();
288 }
289
290 bool ArgumentCoder<ScrollingStateFixedNode>::decode(Decoder& decoder, ScrollingStateFixedNode& node)
291 {
292     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
293         return false;
294
295     if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints)) {
296         FixedPositionViewportConstraints decodedValue;
297         if (!decoder.decode(decodedValue))
298             return false;
299         node.updateConstraints(decodedValue);
300     }
301
302     return true;
303 }
304
305 void ArgumentCoder<ScrollingStateStickyNode>::encode(Encoder& encoder, const ScrollingStateStickyNode& node)
306 {
307     encoder << static_cast<const ScrollingStateNode&>(node);
308     
309     if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints))
310         encoder << node.viewportConstraints();
311 }
312
313 bool ArgumentCoder<ScrollingStateStickyNode>::decode(Decoder& decoder, ScrollingStateStickyNode& node)
314 {
315     if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
316         return false;
317
318     if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints)) {
319         StickyPositionViewportConstraints decodedValue;
320         if (!decoder.decode(decodedValue))
321             return false;
322         node.updateConstraints(decodedValue);
323     }
324
325     return true;
326 }
327
328 namespace WebKit {
329
330 static void encodeNodeAndDescendants(IPC::Encoder& encoder, const ScrollingStateNode& stateNode, int& encodedNodeCount)
331 {
332     ++encodedNodeCount;
333
334     switch (stateNode.nodeType()) {
335     case FrameScrollingNode:
336         encoder << downcast<ScrollingStateFrameScrollingNode>(stateNode);
337         break;
338     case OverflowScrollingNode:
339         encoder << downcast<ScrollingStateOverflowScrollingNode>(stateNode);
340         break;
341     case FixedNode:
342         encoder << downcast<ScrollingStateFixedNode>(stateNode);
343         break;
344     case StickyNode:
345         encoder << downcast<ScrollingStateStickyNode>(stateNode);
346         break;
347     }
348
349     if (!stateNode.children())
350         return;
351
352     for (const auto& child : *stateNode.children())
353         encodeNodeAndDescendants(encoder, *child.get(), encodedNodeCount);
354 }
355
356 void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder& encoder) const
357 {
358     int numNodes = m_scrollingStateTree ? m_scrollingStateTree->nodeCount() : 0;
359     encoder << numNodes;
360     
361     bool hasNewRootNode = m_scrollingStateTree ? m_scrollingStateTree->hasNewRootStateNode() : false;
362     encoder << hasNewRootNode;
363
364     if (m_scrollingStateTree) {
365         encoder << m_scrollingStateTree->hasChangedProperties();
366
367         int numNodesEncoded = 0;
368         if (const ScrollingStateNode* rootNode = m_scrollingStateTree->rootStateNode())
369             encodeNodeAndDescendants(encoder, *rootNode, numNodesEncoded);
370
371         ASSERT_UNUSED(numNodesEncoded, numNodesEncoded == numNodes);
372         encoder << m_scrollingStateTree->removedNodes();
373     } else
374         encoder << Vector<ScrollingNodeID>();
375 }
376
377 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
378 {
379     return transaction.decode(decoder);
380 }
381
382 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder)
383 {
384     int numNodes;
385     if (!decoder.decode(numNodes))
386         return false;
387
388     bool hasNewRootNode;
389     if (!decoder.decode(hasNewRootNode))
390         return false;
391     
392     m_scrollingStateTree = std::make_unique<ScrollingStateTree>();
393
394     bool hasChangedProperties;
395     if (!decoder.decode(hasChangedProperties))
396         return false;
397
398     m_scrollingStateTree->setHasChangedProperties(hasChangedProperties);
399
400     for (int i = 0; i < numNodes; ++i) {
401         ScrollingNodeType nodeType;
402         if (!decoder.decodeEnum(nodeType))
403             return false;
404
405         ScrollingNodeID nodeID;
406         if (!decoder.decode(nodeID))
407             return false;
408
409         ScrollingNodeID parentNodeID;
410         if (!decoder.decode(parentNodeID))
411             return false;
412
413         m_scrollingStateTree->attachNode(nodeType, nodeID, parentNodeID);
414         ScrollingStateNode* newNode = m_scrollingStateTree->stateNodeForID(nodeID);
415         ASSERT(newNode);
416         ASSERT(!parentNodeID || newNode->parent());
417         
418         switch (nodeType) {
419         case FrameScrollingNode:
420             if (!decoder.decode(downcast<ScrollingStateFrameScrollingNode>(*newNode)))
421                 return false;
422             break;
423         case OverflowScrollingNode:
424             if (!decoder.decode(downcast<ScrollingStateOverflowScrollingNode>(*newNode)))
425                 return false;
426             break;
427         case FixedNode:
428             if (!decoder.decode(downcast<ScrollingStateFixedNode>(*newNode)))
429                 return false;
430             break;
431         case StickyNode:
432             if (!decoder.decode(downcast<ScrollingStateStickyNode>(*newNode)))
433                 return false;
434             break;
435         }
436     }
437
438     m_scrollingStateTree->setHasNewRootStateNode(hasNewRootNode);
439
440     // Removed nodes
441     HashSet<ScrollingNodeID> removedNodes;
442     if (!decoder.decode(removedNodes))
443         return false;
444     
445     if (removedNodes.size())
446         m_scrollingStateTree->setRemovedNodes(removedNodes);
447
448     return true;
449 }
450
451 #if !defined(NDEBUG) || !LOG_DISABLED
452
453 static void dump(TextStream& ts, const ScrollingStateScrollingNode& node, bool changedPropertiesOnly)
454 {
455     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaSize))
456         ts.dumpProperty("scrollable-area-size", node.scrollableAreaSize());
457
458     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize))
459         ts.dumpProperty("total-contents-size", node.totalContentsSize());
460
461     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize))
462         ts.dumpProperty("reachable-contents-size", node.reachableContentsSize());
463
464     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition))
465         ts.dumpProperty("scroll-position", node.scrollPosition());
466
467     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
468         ts.dumpProperty("scroll-origin", node.scrollOrigin());
469
470     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
471         ts.dumpProperty("requested-scroll-position", node.requestedScrollPosition());
472         ts.dumpProperty("requested-scroll-position-is-programatic", node.requestedScrollPositionRepresentsProgrammaticScroll());
473     }
474 }
475     
476 static void dump(TextStream& ts, const ScrollingStateFrameScrollingNode& node, bool changedPropertiesOnly)
477 {
478     dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
479     
480     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
481         ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
482
483     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::EventTrackingRegion)) {
484         {
485             TextStream::GroupScope group(ts);
486             ts << "asynchronous-event-tracking-region";
487             for (auto rect : node.eventTrackingRegions().asynchronousDispatchRegion.rects()) {
488                 ts << "\n";
489                 ts.writeIndent();
490                 ts << rect;
491             }
492         }
493         for (const auto& synchronousEventRegion : node.eventTrackingRegions().eventSpecificSynchronousDispatchRegions) {
494             TextStream::GroupScope group(ts);
495             ts << "synchronous-event-tracking-region for event " << synchronousEventRegion.key;
496
497             for (auto rect : synchronousEventRegion.value.rects()) {
498                 ts << "\n";
499                 ts.writeIndent();
500                 ts << rect;
501             }
502         }
503     }
504
505     // FIXME: dump synchronousScrollingReasons
506     // FIXME: dump scrollableAreaParameters
507     // FIXME: dump scrollBehaviorForFixedElements
508
509     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderHeight))
510         ts.dumpProperty("header-height", node.headerHeight());
511
512     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterHeight))
513         ts.dumpProperty("footer-height", node.footerHeight());
514
515     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::TopContentInset))
516         ts.dumpProperty("top-content-inset", node.topContentInset());
517
518     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
519         ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
520
521     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer))
522         ts.dumpProperty("scrolled-contents-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer()));
523
524     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
525         ts.dumpProperty("clip-inset-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer()));
526
527     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
528         ts.dumpProperty("content-shadow-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer()));
529
530     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer))
531         ts.dumpProperty("header-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.headerLayer()));
532
533     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer))
534         ts.dumpProperty("footer-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.footerLayer()));
535 }
536     
537 static void dump(TextStream& ts, const ScrollingStateOverflowScrollingNode& node, bool changedPropertiesOnly)
538 {
539     dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
540     
541     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer))
542         ts.dumpProperty("scrolled-contents-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer()));
543 }
544
545 static void dump(TextStream& ts, const ScrollingStateFixedNode& node, bool changedPropertiesOnly)
546 {
547     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
548         ts << node.viewportConstraints();
549 }
550
551 static void dump(TextStream& ts, const ScrollingStateStickyNode& node, bool changedPropertiesOnly)
552 {
553     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
554         ts << node.viewportConstraints();
555 }
556
557 static void dump(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
558 {
559     ts.dumpProperty("type", node.nodeType());
560
561     if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateNode::ScrollLayer))
562         ts.dumpProperty("layer", static_cast<GraphicsLayer::PlatformLayerID>(node.layer()));
563     
564     switch (node.nodeType()) {
565     case FrameScrollingNode:
566         dump(ts, downcast<ScrollingStateFrameScrollingNode>(node), changedPropertiesOnly);
567         break;
568     case OverflowScrollingNode:
569         dump(ts, downcast<ScrollingStateOverflowScrollingNode>(node), changedPropertiesOnly);
570         break;
571     case FixedNode:
572         dump(ts, downcast<ScrollingStateFixedNode>(node), changedPropertiesOnly);
573         break;
574     case StickyNode:
575         dump(ts, downcast<ScrollingStateStickyNode>(node), changedPropertiesOnly);
576         break;
577     }
578 }
579
580 static void recursiveDumpNodes(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
581 {
582     TextStream::GroupScope group(ts);
583     ts << "node " << node.scrollingNodeID();
584     dump(ts, node, changedPropertiesOnly);
585
586     if (node.children()) {
587         TextStream::GroupScope group(ts);
588         ts << "children";
589
590         for (auto& childNode : *node.children())
591             recursiveDumpNodes(ts, *childNode, changedPropertiesOnly);
592     }
593 }
594
595 static void dump(TextStream& ts, const ScrollingStateTree& stateTree, bool changedPropertiesOnly)
596 {
597     ts.dumpProperty("has changed properties", stateTree.hasChangedProperties());
598     ts.dumpProperty("has new root node", stateTree.hasNewRootStateNode());
599
600     if (stateTree.rootStateNode())
601         recursiveDumpNodes(ts, *stateTree.rootStateNode(), changedPropertiesOnly);
602
603     if (!stateTree.removedNodes().isEmpty()) {
604         Vector<ScrollingNodeID> removedNodes;
605         copyToVector(stateTree.removedNodes(), removedNodes);
606         ts.dumpProperty<Vector<ScrollingNodeID>>("removed-nodes", removedNodes);
607     }
608 }
609
610 WTF::CString RemoteScrollingCoordinatorTransaction::description() const
611 {
612     TextStream ts;
613
614     ts.startGroup();
615     ts << "scrolling state tree";
616
617     if (m_scrollingStateTree) {
618         if (!m_scrollingStateTree->hasChangedProperties())
619             ts << " - no changes";
620         else
621             WebKit::dump(ts, *m_scrollingStateTree.get(), true);
622     } else
623         ts << " - none";
624
625     ts.endGroup();
626
627     return ts.release().utf8();
628 }
629
630 void RemoteScrollingCoordinatorTransaction::dump() const
631 {
632     fprintf(stderr, "%s", description().data());
633 }
634 #endif
635
636 } // namespace WebKit
637
638 #else // !ENABLE(ASYNC_SCROLLING)
639
640 namespace WebKit {
641
642 void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder&) const
643 {
644 }
645
646 bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
647 {
648     return true;
649 }
650
651 } // namespace WebKit
652
653 #endif // ENABLE(ASYNC_SCROLLING)