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