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