FrameView* AsyncScrollingCoordinator::frameViewForScrollingNode(ScrollingNodeID scrollingNodeID) const
{
    if (!m_scrollingStateTree->rootStateNode())
        return nullptr;
    
    if (scrollingNodeID == m_scrollingStateTree->rootStateNode()->scrollingNodeID())
        return m_page->mainFrame().view();

    ScrollingStateNode* stateNode = m_scrollingStateTree->stateNodeForID(scrollingNodeID);
    if (!stateNode)
        return nullptr;

    // Find the enclosing frame scrolling node.
    ScrollingStateNode* parentNode = stateNode;
    while (parentNode && parentNode->nodeType() != FrameScrollingNode)
        parentNode = parentNode->parent();
    
    if (!parentNode)
        return nullptr;
    
    // Walk the frame tree to find the matching FrameView. This is not ideal, but avoids back pointers to FrameViews
    // from ScrollingTreeStateNodes.
    for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
        if (FrameView* view = frame->view()) {
            if (view->scrollLayerID() == parentNode->scrollingNodeID())
                return view;
        }
    }

    return nullptr;
}
Пример #2
0
void RemoteScrollingTreeTextStream::recursiveDumpNodes(const ScrollingStateNode& node, bool changedPropertiesOnly)
{
    RemoteScrollingTreeTextStream& ts = *this;

    ts << "\n";
    ts.increaseIndent();
    ts.writeIndent();
    dump(node, changedPropertiesOnly);

    if (node.children()) {
        ts << "\n";
        ts.increaseIndent();
        ts.writeIndent();
        ts << "(children";
        ts.increaseIndent();

        for (auto& childNode : *node.children())
            recursiveDumpNodes(*childNode, changedPropertiesOnly);

        ts << ")";
        ts.decreaseIndent();
        ts.decreaseIndent();
    }

    ts << ")";
    ts.decreaseIndent();
}
Пример #3
0
ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
{
    ASSERT(newNodeID);

    if (ScrollingStateNode* node = stateNodeForID(newNodeID)) {
        ScrollingStateNode* parent = stateNodeForID(parentID);
        if (!parent)
            return newNodeID;
        if (node->parent() == parent)
            return newNodeID;

        // The node is being re-parented. To do that, we'll remove it, and then re-create a new node.
        removeNode(node);
    }

    ScrollingStateNode* newNode = 0;
    if (!parentID) {
        // If we're resetting the root node, we should clear the HashMap and destroy the current children.
        clear();

        setRootStateNode(ScrollingStateFrameScrollingNode::create(*this, newNodeID));
        newNode = rootStateNode();
        m_hasNewRootStateNode = true;
    } else {
        ScrollingStateNode* parent = stateNodeForID(parentID);
        if (!parent)
            return 0;

        switch (nodeType) {
        case FixedNode: {
            OwnPtr<ScrollingStateFixedNode> fixedNode = ScrollingStateFixedNode::create(*this, newNodeID);
            newNode = fixedNode.get();
            parent->appendChild(fixedNode.release());
            break;
        }
        case StickyNode: {
            OwnPtr<ScrollingStateStickyNode> stickyNode = ScrollingStateStickyNode::create(*this, newNodeID);
            newNode = stickyNode.get();
            parent->appendChild(stickyNode.release());
            break;
        }
        case FrameScrollingNode: {
            OwnPtr<ScrollingStateFrameScrollingNode> scrollingNode = ScrollingStateFrameScrollingNode::create(*this, newNodeID);
            newNode = scrollingNode.get();
            parent->appendChild(scrollingNode.release());
            break;
        }
        case OverflowScrollingNode: {
            OwnPtr<ScrollingStateOverflowScrollingNode> scrollingNode = ScrollingStateOverflowScrollingNode::create(*this, newNodeID);
            newNode = scrollingNode.get();
            parent->appendChild(scrollingNode.release());
            break;
        }
        }
    }

    m_stateNodeMap.set(newNodeID, newNode);
    return newNodeID;
}
Пример #4
0
bool RemoteScrollingCoordinatorTransaction::decode(IPC::ArgumentDecoder& decoder)
{
    int numNodes;
    if (!decoder.decode(numNodes))
        return false;

    bool hasNewRootNode;
    if (!decoder.decode(hasNewRootNode))
        return false;
    
    m_scrollingStateTree = ScrollingStateTree::create();
    
    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:
        case OverflowScrollingNode:
            if (!decoder.decode(*toScrollingStateScrollingNode(newNode)))
                return false;
            break;
        case FixedNode:
            if (!decoder.decode(*toScrollingStateFixedNode(newNode)))
                return false;
            break;
        case StickyNode:
            if (!decoder.decode(*toScrollingStateStickyNode(newNode)))
                return false;
            break;
        }
    }

    m_scrollingStateTree->setHasNewRootStateNode(hasNewRootNode);

    // Removed nodes
    Vector<ScrollingNodeID> removedNodes;
    if (!decoder.decode(removedNodes))
        return false;
    
    if (removedNodes.size())
        m_scrollingStateTree->setRemovedNodes(removedNodes);

    return true;
}
Пример #5
0
void ScrollingCoordinatorCoordinatedGraphics::detachFromStateTree(ScrollingNodeID nodeID)
{
    ScrollingStateNode* node = m_scrollingStateTree->stateNodeForID(nodeID);
    if (node && node->nodeType() == FixedNode)
        toCoordinatedGraphicsLayer(node->layer())->setFixedToViewport(false);

    m_scrollingStateTree->detachNode(nodeID);
}
Пример #6
0
// This copy constructor is used for cloning nodes in the tree, and it doesn't make sense
// to clone the relationship pointers, so don't copy that information from the original
// node.
ScrollingStateNode::ScrollingStateNode(const ScrollingStateNode& stateNode)
    : m_scrollingStateTree(0)
    , m_nodeID(stateNode.scrollingNodeID())
    , m_changedProperties(stateNode.changedProperties())
    , m_parent(0)
{
    // FIXME: why doesn't this set the GraphicsLayer?
    setScrollPlatformLayer(stateNode.platformScrollLayer());
}
Пример #7
0
// This copy constructor is used for cloning nodes in the tree, and it doesn't make sense
// to clone the relationship pointers, so don't copy that information from the original node.
ScrollingStateNode::ScrollingStateNode(const ScrollingStateNode& stateNode, ScrollingStateTree& adoptiveTree)
    : m_nodeType(stateNode.nodeType())
    , m_nodeID(stateNode.scrollingNodeID())
    , m_changedProperties(stateNode.changedProperties())
    , m_scrollingStateTree(adoptiveTree)
    , m_parent(nullptr)
{
    if (hasChangedProperty(ScrollLayer))
        setLayer(stateNode.layer().toRepresentation(adoptiveTree.preferredLayerRepresentation()));
    scrollingStateTree().addNode(this);
}
Пример #8
0
void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree& stateTree, const RemoteLayerTreeHost& layerTreeHost)
{
    for (auto it : stateTree.nodeMap()) {
        ScrollingStateNode* currNode = it.value;
        switch (currNode->nodeType()) {
        case ScrollingNode: {
            ScrollingStateScrollingNode* scrollingStateNode = toScrollingStateScrollingNode(currNode);
            
            if (scrollingStateNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
                scrollingStateNode->setLayer(layerTreeHost.getLayer(scrollingStateNode->layer()));

            if (scrollingStateNode->hasChangedProperty(ScrollingStateScrollingNode::CounterScrollingLayer))
                scrollingStateNode->setCounterScrollingLayer(layerTreeHost.getLayer(scrollingStateNode->counterScrollingLayer()));

            // FIXME: we should never have header and footer layers coming from the WebProcess.
            if (scrollingStateNode->hasChangedProperty(ScrollingStateScrollingNode::HeaderLayer))
                scrollingStateNode->setHeaderLayer(layerTreeHost.getLayer(scrollingStateNode->headerLayer()));

            if (scrollingStateNode->hasChangedProperty(ScrollingStateScrollingNode::FooterLayer))
                scrollingStateNode->setFooterLayer(layerTreeHost.getLayer(scrollingStateNode->footerLayer()));
            break;
        }
        case FixedNode:
            if (currNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
                currNode->setLayer(layerTreeHost.getLayer(currNode->layer()));
            break;
        case StickyNode:
            if (currNode->hasChangedProperty(ScrollingStateNode::ScrollLayer))
                currNode->setLayer(layerTreeHost.getLayer(currNode->layer()));
            break;
        }
    }
}
ScrollingNodeID ScrollingStateTree::attachNode(ScrollingNodeType nodeType, ScrollingNodeID newNodeID, ScrollingNodeID parentID)
{
    ASSERT(newNodeID);
    if (ScrollingStateNode* node = stateNodeForID(newNodeID)) {
        if (!parentID)
            return newNodeID;

        ScrollingStateNode* parent = stateNodeForID(parentID);
        if (!parent)
            return newNodeID;

        if (node->parent() == parent)
            return newNodeID;

        // The node is being re-parented. To do that, we'll remove it, and then re-create a new node.
        removeNodeAndAllDescendants(node, SubframeNodeRemoval::Orphan);
    }

    ScrollingStateNode* newNode = nullptr;
    if (!parentID) {
        // If we're resetting the root node, we should clear the HashMap and destroy the current children.
        clear();

        setRootStateNode(ScrollingStateFrameScrollingNode::create(*this, newNodeID));
        newNode = rootStateNode();
        m_hasNewRootStateNode = true;
    } else {
        ScrollingStateNode* parent = stateNodeForID(parentID);
        if (!parent)
            return 0;

        if (nodeType == FrameScrollingNode && parentID) {
            if (RefPtr<ScrollingStateNode> orphanedNode = m_orphanedSubframeNodes.take(newNodeID)) {
                newNode = orphanedNode.get();
                parent->appendChild(orphanedNode.release());
            }
        }

        if (!newNode) {
            RefPtr<ScrollingStateNode> stateNode = createNode(nodeType, newNodeID);
            newNode = stateNode.get();
            parent->appendChild(stateNode.release());
        }
    }

    m_stateNodeMap.set(newNodeID, newNode);
    m_nodesRemovedSinceLastCommit.remove(newNodeID);
    return newNodeID;
}
void AsyncScrollingCoordinator::syncChildPositions(const LayoutRect& viewportRect)
{
    if (!m_scrollingStateTree->rootStateNode())
        return;

    Vector<OwnPtr<ScrollingStateNode>>* children = m_scrollingStateTree->rootStateNode()->children();
    if (!children)
        return;

    // FIXME: We'll have to traverse deeper into the tree at some point.
    size_t size = children->size();
    for (size_t i = 0; i < size; ++i) {
        ScrollingStateNode* child = children->at(i).get();
        child->syncLayerPositionForViewportRect(viewportRect);
    }
}
Пример #11
0
void ScrollingStateNode::cloneAndResetChildren(ScrollingStateNode& clone, ScrollingStateTree& adoptiveTree)
{
    if (!m_children)
        return;

    for (auto& child : *m_children)
        clone.appendChild(child->cloneAndReset(adoptiveTree));
}
Пример #12
0
bool ArgumentCoder<ScrollingStateNode>::decode(ArgumentDecoder& 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;
}
void ScrollingStateTree::removeNodeAndAllDescendants(ScrollingStateNode* node, SubframeNodeRemoval subframeNodeRemoval)
{
    ScrollingStateNode* parent = node->parent();

    recursiveNodeWillBeRemoved(node, subframeNodeRemoval);

    if (node == m_rootStateNode)
        m_rootStateNode = nullptr;
    else if (parent) {
        ASSERT(parent->children() && parent->children()->find(node) != notFound);
        if (auto children = parent->children()) {
            size_t index = children->find(node);
            if (index != notFound)
                children->remove(index);
        }
    }
}
Пример #14
0
static void encodeNodeAndDescendants(IPC::ArgumentEncoder& encoder, const ScrollingStateNode& stateNode)
{
    switch (stateNode.nodeType()) {
    case FrameScrollingNode:
    case OverflowScrollingNode:
        encoder << toScrollingStateScrollingNode(stateNode);
        break;
    case FixedNode:
        encoder << toScrollingStateFixedNode(stateNode);
        break;
    case StickyNode:
        encoder << toScrollingStateStickyNode(stateNode);
        break;
    }

    if (!stateNode.children())
        return;

    for (size_t i = 0; i < stateNode.children()->size(); ++i) {
        const OwnPtr<ScrollingStateNode>& child = stateNode.children()->at(i);
        encodeNodeAndDescendants(encoder, *child.get());
    }
}
Пример #15
0
void RemoteScrollingTreeTextStream::dump(const ScrollingStateNode& node, bool changedPropertiesOnly)
{
    RemoteScrollingTreeTextStream& ts = *this;

    ts << "(node " << node.scrollingNodeID();

    dumpProperty(ts, "type", node.nodeType());

    if (!changedPropertiesOnly || node.hasChangedProperty(ScrollingStateNode::ScrollLayer))
        dumpProperty(ts, "layer", static_cast<GraphicsLayer::PlatformLayerID>(node.layer()));
    
    switch (node.nodeType()) {
    case FrameScrollingNode:
    case OverflowScrollingNode:
        dump(toScrollingStateScrollingNode(node), changedPropertiesOnly);
        break;
    case FixedNode:
        dump(toScrollingStateFixedNode(node), changedPropertiesOnly);
        break;
    case StickyNode:
        dump(toScrollingStateStickyNode(node), changedPropertiesOnly);
        break;
    }
}
Пример #16
0
void ArgumentCoder<ScrollingStateNode>::encode(ArgumentEncoder& 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());
}