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