summaryrefslogtreecommitdiff
path: root/Source/WebKit2/Shared/Scrolling
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/Shared/Scrolling')
-rw-r--r--Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp665
-rw-r--r--Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.h63
2 files changed, 728 insertions, 0 deletions
diff --git a/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp b/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp
new file mode 100644
index 000000000..a055701a4
--- /dev/null
+++ b/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp
@@ -0,0 +1,665 @@
+/*
+ * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RemoteScrollingCoordinatorTransaction.h"
+
+#include "ArgumentCoders.h"
+#include "WebCoreArgumentCoders.h"
+#include <WebCore/GraphicsLayer.h>
+#include <WebCore/ScrollingStateFixedNode.h>
+#include <WebCore/ScrollingStateFrameScrollingNode.h>
+#include <WebCore/ScrollingStateOverflowScrollingNode.h>
+#include <WebCore/ScrollingStateStickyNode.h>
+#include <WebCore/ScrollingStateTree.h>
+#include <WebCore/TextStream.h>
+#include <wtf/HashMap.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+
+#if ENABLE(ASYNC_SCROLLING)
+
+namespace IPC {
+
+template<> struct ArgumentCoder<ScrollingStateNode> {
+ static void encode(Encoder&, const ScrollingStateNode&);
+ static bool decode(Decoder&, ScrollingStateNode&);
+};
+
+template<> struct ArgumentCoder<ScrollingStateScrollingNode> {
+ static void encode(Encoder&, const ScrollingStateScrollingNode&);
+ static bool decode(Decoder&, ScrollingStateScrollingNode&);
+};
+
+template<> struct ArgumentCoder<ScrollingStateFrameScrollingNode> {
+ static void encode(Encoder&, const ScrollingStateFrameScrollingNode&);
+ static bool decode(Decoder&, ScrollingStateFrameScrollingNode&);
+};
+
+template<> struct ArgumentCoder<ScrollingStateOverflowScrollingNode> {
+ static void encode(Encoder&, const ScrollingStateOverflowScrollingNode&);
+ static bool decode(Decoder&, ScrollingStateOverflowScrollingNode&);
+};
+
+template<> struct ArgumentCoder<ScrollingStateFixedNode> {
+ static void encode(Encoder&, const ScrollingStateFixedNode&);
+ static bool decode(Decoder&, ScrollingStateFixedNode&);
+};
+
+template<> struct ArgumentCoder<ScrollingStateStickyNode> {
+ static void encode(Encoder&, const ScrollingStateStickyNode&);
+ static bool decode(Decoder&, ScrollingStateStickyNode&);
+};
+
+} // namespace IPC
+
+using namespace IPC;
+
+void ArgumentCoder<ScrollingStateNode>::encode(Encoder& encoder, const ScrollingStateNode& node)
+{
+ encoder.encodeEnum(node.nodeType());
+ encoder << node.scrollingNodeID();
+ encoder << node.parentNodeID();
+ encoder << node.changedProperties();
+
+ if (node.hasChangedProperty(ScrollingStateNode::ScrollLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.layer());
+}
+
+bool ArgumentCoder<ScrollingStateNode>::decode(Decoder& decoder, ScrollingStateNode& node)
+{
+ // nodeType, scrollingNodeID and parentNodeID have already been decoded by the caller in order to create the node.
+ ScrollingStateNode::ChangedProperties changedProperties;
+ if (!decoder.decode(changedProperties))
+ return false;
+
+ node.setChangedProperties(changedProperties);
+ if (node.hasChangedProperty(ScrollingStateNode::ScrollLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setLayer(layerID);
+ }
+
+ return true;
+}
+
+#define SCROLLING_NODE_ENCODE(property, getter) \
+ if (node.hasChangedProperty(property)) \
+ encoder << node.getter();
+
+#define SCROLLING_NODE_ENCODE_ENUM(property, getter) \
+ if (node.hasChangedProperty(property)) \
+ encoder.encodeEnum(node.getter());
+
+void ArgumentCoder<ScrollingStateScrollingNode>::encode(Encoder& encoder, const ScrollingStateScrollingNode& node)
+{
+ encoder << static_cast<const ScrollingStateNode&>(node);
+
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaSize, scrollableAreaSize)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::TotalContentsSize, totalContentsSize)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ReachableContentsSize, reachableContentsSize)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollPosition, scrollPosition)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollOrigin, scrollOrigin)
+#if ENABLE(CSS_SCROLL_SNAP)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, horizontalSnapOffsets)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsets, verticalSnapOffsets)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::HorizontalSnapOffsetRanges, horizontalSnapOffsetRanges)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::VerticalSnapOffsetRanges, verticalSnapOffsetRanges)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, currentHorizontalSnapPointIndex)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, currentVerticalSnapPointIndex)
+#endif
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::ScrollableAreaParams, scrollableAreaParameters)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPosition)
+ SCROLLING_NODE_ENCODE(ScrollingStateScrollingNode::RequestedScrollPosition, requestedScrollPositionRepresentsProgrammaticScroll)
+}
+
+void ArgumentCoder<ScrollingStateFrameScrollingNode>::encode(Encoder& encoder, const ScrollingStateFrameScrollingNode& node)
+{
+ encoder << static_cast<const ScrollingStateScrollingNode&>(node);
+
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, frameScaleFactor)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, eventTrackingRegions)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, synchronousScrollingReasons)
+ SCROLLING_NODE_ENCODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, scrollBehaviorForFixedElements)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::HeaderHeight, headerHeight)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FooterHeight, footerHeight)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::TopContentInset, topContentInset)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, fixedElementsLayoutRelativeToFrame)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::VisualViewportEnabled, visualViewportEnabled)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::LayoutViewport, layoutViewport)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MinLayoutViewportOrigin, minLayoutViewportOrigin)
+ SCROLLING_NODE_ENCODE(ScrollingStateFrameScrollingNode::MaxLayoutViewportOrigin, maxLayoutViewportOrigin)
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer());
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.counterScrollingLayer());
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer());
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer());
+}
+
+void ArgumentCoder<ScrollingStateOverflowScrollingNode>::encode(Encoder& encoder, const ScrollingStateOverflowScrollingNode& node)
+{
+ encoder << static_cast<const ScrollingStateScrollingNode&>(node);
+
+ if (node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer))
+ encoder << static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer());
+}
+
+#define SCROLLING_NODE_DECODE(property, type, setter) \
+ if (node.hasChangedProperty(property)) { \
+ type decodedValue; \
+ if (!decoder.decode(decodedValue)) \
+ return false; \
+ node.setter(decodedValue); \
+ }
+
+#define SCROLLING_NODE_DECODE_ENUM(property, type, setter) \
+ if (node.hasChangedProperty(property)) { \
+ type decodedValue; \
+ if (!decoder.decodeEnum(decodedValue)) \
+ return false; \
+ node.setter(decodedValue); \
+ }
+
+bool ArgumentCoder<ScrollingStateScrollingNode>::decode(Decoder& decoder, ScrollingStateScrollingNode& node)
+{
+ if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
+ return false;
+
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaSize, FloatSize, setScrollableAreaSize);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::TotalContentsSize, FloatSize, setTotalContentsSize);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ReachableContentsSize, FloatSize, setReachableContentsSize);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollPosition, FloatPoint, setScrollPosition);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollOrigin, IntPoint, setScrollOrigin);
+#if ENABLE(CSS_SCROLL_SNAP)
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsets, Vector<float>, setHorizontalSnapOffsets);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsets, Vector<float>, setVerticalSnapOffsets);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::HorizontalSnapOffsetRanges, Vector<ScrollOffsetRange<float>>, setHorizontalSnapOffsetRanges)
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::VerticalSnapOffsetRanges, Vector<ScrollOffsetRange<float>>, setVerticalSnapOffsetRanges)
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentHorizontalSnapOffsetIndex, unsigned, setCurrentHorizontalSnapPointIndex);
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::CurrentVerticalSnapOffsetIndex, unsigned, setCurrentVerticalSnapPointIndex);
+#endif
+ SCROLLING_NODE_DECODE(ScrollingStateScrollingNode::ScrollableAreaParams, ScrollableAreaParameters, setScrollableAreaParameters);
+
+ if (node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
+ FloatPoint scrollPosition;
+ if (!decoder.decode(scrollPosition))
+ return false;
+
+ bool representsProgrammaticScroll;
+ if (!decoder.decode(representsProgrammaticScroll))
+ return false;
+
+ node.setRequestedScrollPosition(scrollPosition, representsProgrammaticScroll);
+ }
+
+ return true;
+}
+
+bool ArgumentCoder<ScrollingStateFrameScrollingNode>::decode(Decoder& decoder, ScrollingStateFrameScrollingNode& node)
+{
+ if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
+ return false;
+
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FrameScaleFactor, float, setFrameScaleFactor);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::EventTrackingRegion, EventTrackingRegions, setEventTrackingRegions);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::ReasonsForSynchronousScrolling, SynchronousScrollingReasons, setSynchronousScrollingReasons);
+ SCROLLING_NODE_DECODE_ENUM(ScrollingStateFrameScrollingNode::BehaviorForFixedElements, ScrollBehaviorForFixedElements, setScrollBehaviorForFixedElements);
+
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::HeaderHeight, int, setHeaderHeight);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FooterHeight, int, setFooterHeight);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::TopContentInset, float, setTopContentInset);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::FixedElementsLayoutRelativeToFrame, bool, setFixedElementsLayoutRelativeToFrame);
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::VisualViewportEnabled, bool, setVisualViewportEnabled)
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::LayoutViewport, FloatRect, setLayoutViewport)
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::MinLayoutViewportOrigin, FloatPoint, setMinLayoutViewportOrigin)
+ SCROLLING_NODE_DECODE(ScrollingStateFrameScrollingNode::MaxLayoutViewportOrigin, FloatPoint, setMaxLayoutViewportOrigin)
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setScrolledContentsLayer(layerID);
+ }
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setCounterScrollingLayer(layerID);
+ }
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setInsetClipLayer(layerID);
+ }
+
+ if (node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setContentShadowLayer(layerID);
+ }
+
+ return true;
+}
+
+bool ArgumentCoder<ScrollingStateOverflowScrollingNode>::decode(Decoder& decoder, ScrollingStateOverflowScrollingNode& node)
+{
+ if (!decoder.decode(static_cast<ScrollingStateScrollingNode&>(node)))
+ return false;
+
+ if (node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer)) {
+ GraphicsLayer::PlatformLayerID layerID;
+ if (!decoder.decode(layerID))
+ return false;
+ node.setScrolledContentsLayer(layerID);
+ }
+
+ return true;
+}
+
+void ArgumentCoder<ScrollingStateFixedNode>::encode(Encoder& encoder, const ScrollingStateFixedNode& node)
+{
+ encoder << static_cast<const ScrollingStateNode&>(node);
+
+ if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
+ encoder << node.viewportConstraints();
+}
+
+bool ArgumentCoder<ScrollingStateFixedNode>::decode(Decoder& decoder, ScrollingStateFixedNode& node)
+{
+ if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
+ return false;
+
+ if (node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints)) {
+ FixedPositionViewportConstraints decodedValue;
+ if (!decoder.decode(decodedValue))
+ return false;
+ node.updateConstraints(decodedValue);
+ }
+
+ return true;
+}
+
+void ArgumentCoder<ScrollingStateStickyNode>::encode(Encoder& encoder, const ScrollingStateStickyNode& node)
+{
+ encoder << static_cast<const ScrollingStateNode&>(node);
+
+ if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints))
+ encoder << node.viewportConstraints();
+}
+
+bool ArgumentCoder<ScrollingStateStickyNode>::decode(Decoder& decoder, ScrollingStateStickyNode& node)
+{
+ if (!decoder.decode(static_cast<ScrollingStateNode&>(node)))
+ return false;
+
+ if (node.hasChangedProperty(ScrollingStateStickyNode::ViewportConstraints)) {
+ StickyPositionViewportConstraints decodedValue;
+ if (!decoder.decode(decodedValue))
+ return false;
+ node.updateConstraints(decodedValue);
+ }
+
+ return true;
+}
+
+namespace WebKit {
+
+static void encodeNodeAndDescendants(IPC::Encoder& encoder, const ScrollingStateNode& stateNode, int& encodedNodeCount)
+{
+ ++encodedNodeCount;
+
+ switch (stateNode.nodeType()) {
+ case FrameScrollingNode:
+ encoder << downcast<ScrollingStateFrameScrollingNode>(stateNode);
+ break;
+ case OverflowScrollingNode:
+ encoder << downcast<ScrollingStateOverflowScrollingNode>(stateNode);
+ break;
+ case FixedNode:
+ encoder << downcast<ScrollingStateFixedNode>(stateNode);
+ break;
+ case StickyNode:
+ encoder << downcast<ScrollingStateStickyNode>(stateNode);
+ break;
+ }
+
+ if (!stateNode.children())
+ return;
+
+ for (const auto& child : *stateNode.children())
+ encodeNodeAndDescendants(encoder, *child.get(), encodedNodeCount);
+}
+
+void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder& encoder) const
+{
+ int numNodes = m_scrollingStateTree ? m_scrollingStateTree->nodeCount() : 0;
+ encoder << numNodes;
+
+ bool hasNewRootNode = m_scrollingStateTree ? m_scrollingStateTree->hasNewRootStateNode() : false;
+ encoder << hasNewRootNode;
+
+ if (m_scrollingStateTree) {
+ encoder << m_scrollingStateTree->hasChangedProperties();
+
+ int numNodesEncoded = 0;
+ if (const ScrollingStateNode* rootNode = m_scrollingStateTree->rootStateNode())
+ encodeNodeAndDescendants(encoder, *rootNode, numNodesEncoded);
+
+ ASSERT_UNUSED(numNodesEncoded, numNodesEncoded == numNodes);
+ encoder << m_scrollingStateTree->removedNodes();
+ } else
+ encoder << Vector<ScrollingNodeID>();
+}
+
+bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
+{
+ return transaction.decode(decoder);
+}
+
+bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder)
+{
+ int numNodes;
+ if (!decoder.decode(numNodes))
+ return false;
+
+ bool hasNewRootNode;
+ if (!decoder.decode(hasNewRootNode))
+ return false;
+
+ m_scrollingStateTree = std::make_unique<ScrollingStateTree>();
+
+ bool hasChangedProperties;
+ if (!decoder.decode(hasChangedProperties))
+ return false;
+
+ m_scrollingStateTree->setHasChangedProperties(hasChangedProperties);
+
+ for (int i = 0; i < numNodes; ++i) {
+ ScrollingNodeType nodeType;
+ if (!decoder.decodeEnum(nodeType))
+ return false;
+
+ ScrollingNodeID nodeID;
+ if (!decoder.decode(nodeID))
+ return false;
+
+ ScrollingNodeID parentNodeID;
+ if (!decoder.decode(parentNodeID))
+ return false;
+
+ m_scrollingStateTree->attachNode(nodeType, nodeID, parentNodeID);
+ ScrollingStateNode* newNode = m_scrollingStateTree->stateNodeForID(nodeID);
+ ASSERT(newNode);
+ ASSERT(!parentNodeID || newNode->parent());
+
+ switch (nodeType) {
+ case FrameScrollingNode:
+ if (!decoder.decode(downcast<ScrollingStateFrameScrollingNode>(*newNode)))
+ return false;
+ break;
+ case OverflowScrollingNode:
+ if (!decoder.decode(downcast<ScrollingStateOverflowScrollingNode>(*newNode)))
+ return false;
+ break;
+ case FixedNode:
+ if (!decoder.decode(downcast<ScrollingStateFixedNode>(*newNode)))
+ return false;
+ break;
+ case StickyNode:
+ if (!decoder.decode(downcast<ScrollingStateStickyNode>(*newNode)))
+ return false;
+ break;
+ }
+ }
+
+ m_scrollingStateTree->setHasNewRootStateNode(hasNewRootNode);
+
+ // Removed nodes
+ HashSet<ScrollingNodeID> removedNodes;
+ if (!decoder.decode(removedNodes))
+ return false;
+
+ if (removedNodes.size())
+ m_scrollingStateTree->setRemovedNodes(removedNodes);
+
+ return true;
+}
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+
+static void dump(TextStream& ts, const ScrollingStateScrollingNode& node, bool changedPropertiesOnly)
+{
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaSize))
+ ts.dumpProperty("scrollable-area-size", node.scrollableAreaSize());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize))
+ ts.dumpProperty("total-contents-size", node.totalContentsSize());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ReachableContentsSize))
+ ts.dumpProperty("reachable-contents-size", node.reachableContentsSize());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollPosition))
+ ts.dumpProperty("scroll-position", node.scrollPosition());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::ScrollOrigin))
+ ts.dumpProperty("scroll-origin", node.scrollOrigin());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) {
+ ts.dumpProperty("requested-scroll-position", node.requestedScrollPosition());
+ ts.dumpProperty("requested-scroll-position-is-programatic", node.requestedScrollPositionRepresentsProgrammaticScroll());
+ }
+}
+
+static void dump(TextStream& ts, const ScrollingStateFrameScrollingNode& node, bool changedPropertiesOnly)
+{
+ dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
+ ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::EventTrackingRegion)) {
+ {
+ TextStream::GroupScope group(ts);
+ ts << "asynchronous-event-tracking-region";
+ for (auto rect : node.eventTrackingRegions().asynchronousDispatchRegion.rects()) {
+ ts << "\n";
+ ts.writeIndent();
+ ts << rect;
+ }
+ }
+ for (const auto& synchronousEventRegion : node.eventTrackingRegions().eventSpecificSynchronousDispatchRegions) {
+ TextStream::GroupScope group(ts);
+ ts << "synchronous-event-tracking-region for event " << synchronousEventRegion.key;
+
+ for (auto rect : synchronousEventRegion.value.rects()) {
+ ts << "\n";
+ ts.writeIndent();
+ ts << rect;
+ }
+ }
+ }
+
+ // FIXME: dump synchronousScrollingReasons
+ // FIXME: dump scrollableAreaParameters
+ // FIXME: dump scrollBehaviorForFixedElements
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderHeight))
+ ts.dumpProperty("header-height", node.headerHeight());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterHeight))
+ ts.dumpProperty("footer-height", node.footerHeight());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::TopContentInset))
+ ts.dumpProperty("top-content-inset", node.topContentInset());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FrameScaleFactor))
+ ts.dumpProperty("frame-scale-factor", node.frameScaleFactor());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer))
+ ts.dumpProperty("scrolled-contents-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer()));
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer))
+ ts.dumpProperty("clip-inset-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.insetClipLayer()));
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer))
+ ts.dumpProperty("content-shadow-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.contentShadowLayer()));
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer))
+ ts.dumpProperty("header-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.headerLayer()));
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer))
+ ts.dumpProperty("footer-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.footerLayer()));
+}
+
+static void dump(TextStream& ts, const ScrollingStateOverflowScrollingNode& node, bool changedPropertiesOnly)
+{
+ dump(ts, static_cast<const ScrollingStateScrollingNode&>(node), changedPropertiesOnly);
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer))
+ ts.dumpProperty("scrolled-contents-layer", static_cast<GraphicsLayer::PlatformLayerID>(node.scrolledContentsLayer()));
+}
+
+static void dump(TextStream& ts, const ScrollingStateFixedNode& node, bool changedPropertiesOnly)
+{
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
+ ts << node.viewportConstraints();
+}
+
+static void dump(TextStream& ts, const ScrollingStateStickyNode& node, bool changedPropertiesOnly)
+{
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateFixedNode::ViewportConstraints))
+ ts << node.viewportConstraints();
+}
+
+static void dump(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
+{
+ ts.dumpProperty("type", node.nodeType());
+
+ if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateNode::ScrollLayer))
+ ts.dumpProperty("layer", static_cast<GraphicsLayer::PlatformLayerID>(node.layer()));
+
+ switch (node.nodeType()) {
+ case FrameScrollingNode:
+ dump(ts, downcast<ScrollingStateFrameScrollingNode>(node), changedPropertiesOnly);
+ break;
+ case OverflowScrollingNode:
+ dump(ts, downcast<ScrollingStateOverflowScrollingNode>(node), changedPropertiesOnly);
+ break;
+ case FixedNode:
+ dump(ts, downcast<ScrollingStateFixedNode>(node), changedPropertiesOnly);
+ break;
+ case StickyNode:
+ dump(ts, downcast<ScrollingStateStickyNode>(node), changedPropertiesOnly);
+ break;
+ }
+}
+
+static void recursiveDumpNodes(TextStream& ts, const ScrollingStateNode& node, bool changedPropertiesOnly)
+{
+ TextStream::GroupScope group(ts);
+ ts << "node " << node.scrollingNodeID();
+ dump(ts, node, changedPropertiesOnly);
+
+ if (node.children()) {
+ TextStream::GroupScope group(ts);
+ ts << "children";
+
+ for (auto& childNode : *node.children())
+ recursiveDumpNodes(ts, *childNode, changedPropertiesOnly);
+ }
+}
+
+static void dump(TextStream& ts, const ScrollingStateTree& stateTree, bool changedPropertiesOnly)
+{
+ ts.dumpProperty("has changed properties", stateTree.hasChangedProperties());
+ ts.dumpProperty("has new root node", stateTree.hasNewRootStateNode());
+
+ if (stateTree.rootStateNode())
+ recursiveDumpNodes(ts, *stateTree.rootStateNode(), changedPropertiesOnly);
+
+ if (!stateTree.removedNodes().isEmpty()) {
+ Vector<ScrollingNodeID> removedNodes;
+ copyToVector(stateTree.removedNodes(), removedNodes);
+ ts.dumpProperty<Vector<ScrollingNodeID>>("removed-nodes", removedNodes);
+ }
+}
+
+WTF::CString RemoteScrollingCoordinatorTransaction::description() const
+{
+ TextStream ts;
+
+ ts.startGroup();
+ ts << "scrolling state tree";
+
+ if (m_scrollingStateTree) {
+ if (!m_scrollingStateTree->hasChangedProperties())
+ ts << " - no changes";
+ else
+ WebKit::dump(ts, *m_scrollingStateTree.get(), true);
+ } else
+ ts << " - none";
+
+ ts.endGroup();
+
+ return ts.release().utf8();
+}
+
+void RemoteScrollingCoordinatorTransaction::dump() const
+{
+ fprintf(stderr, "%s", description().data());
+}
+#endif
+
+} // namespace WebKit
+
+#else // !ENABLE(ASYNC_SCROLLING)
+
+namespace WebKit {
+
+void RemoteScrollingCoordinatorTransaction::encode(IPC::Encoder&) const
+{
+}
+
+bool RemoteScrollingCoordinatorTransaction::decode(IPC::Decoder& decoder, RemoteScrollingCoordinatorTransaction& transaction)
+{
+ return true;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(ASYNC_SCROLLING)
diff --git a/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.h b/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.h
new file mode 100644
index 000000000..8b9b0bf87
--- /dev/null
+++ b/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RemoteScrollingCoordinatorTransaction_h
+#define RemoteScrollingCoordinatorTransaction_h
+
+#include <WebCore/ScrollingStateTree.h>
+
+namespace IPC {
+class Decoder;
+class Encoder;
+}
+
+namespace WebKit {
+
+class RemoteScrollingCoordinatorTransaction {
+public:
+#if ENABLE(ASYNC_SCROLLING)
+ void setStateTreeToEncode(std::unique_ptr<WebCore::ScrollingStateTree> stateTree) { m_scrollingStateTree = WTFMove(stateTree); }
+ std::unique_ptr<WebCore::ScrollingStateTree>& scrollingStateTree() { return m_scrollingStateTree; }
+#endif // ENABLE(ASYNC_SCROLLING)
+
+ void encode(IPC::Encoder&) const;
+ static bool decode(IPC::Decoder&, RemoteScrollingCoordinatorTransaction&);
+
+#if !defined(NDEBUG) || !LOG_DISABLED
+ WTF::CString description() const;
+ void dump() const;
+#endif
+
+private:
+#if ENABLE(ASYNC_SCROLLING)
+ bool decode(IPC::Decoder&);
+
+ std::unique_ptr<WebCore::ScrollingStateTree> m_scrollingStateTree;
+#endif // ENABLE(ASYNC_SCROLLING)
+};
+
+} // namespace WebKit
+
+#endif // RemoteScrollingCoordinatorTransaction_h