Changeset 170197 in webkit
- Timestamp:
- Jun 20, 2014, 12:14:50 PM (11 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/WebCore.exp.in (modified) (1 diff)
-
WebCore/page/scrolling/ScrollingStateTree.cpp (modified) (3 diffs)
-
WebCore/page/scrolling/ScrollingStateTree.h (modified) (2 diffs)
-
WebCore/page/scrolling/ScrollingTree.cpp (modified) (4 diffs)
-
WebCore/page/scrolling/ScrollingTree.h (modified) (1 diff)
-
WebCore/page/scrolling/ScrollingTreeNode.h (modified) (2 diffs)
-
WebKit2/ChangeLog (modified) (1 diff)
-
WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r170196 r170197 1 2014-06-19 Simon Fraser <simon.fraser@apple.com> 2 3 Handle scrolling tree modifications which remove intermediate nodes 4 https://bugs.webkit.org/show_bug.cgi?id=134082 5 6 Reviewed by Tim Horton. 7 8 When updating the scrolling tree from the state tree, we failed to maintain 9 the children arrays correctly. Fix by removing all children on scrolling nodes, 10 and allowing the calls on children to add them back. A temporary hash map 11 keeps the nodes alive. 12 13 The state tree's m_nodesRemovedSinceLastCommit was also made into a HashSet, 14 to make it easier to handle removal followed by re-insertion. 15 16 * WebCore.exp.in: 17 * page/scrolling/ScrollingStateTree.cpp: 18 (WebCore::ScrollingStateTree::attachNode): If a node is (possibly re-)added, 19 remove it from m_nodesRemovedSinceLastCommit.remove. 20 (WebCore::ScrollingStateTree::willRemoveNode): 21 (WebCore::ScrollingStateTree::setRemovedNodes): 22 * page/scrolling/ScrollingStateTree.h: 23 (WebCore::ScrollingStateTree::removedNodes): 24 * page/scrolling/ScrollingTree.cpp: 25 (WebCore::ScrollingTree::commitNewTreeState): 26 (WebCore::ScrollingTree::updateTreeFromStateNode): Clean up to have only one call 27 to updateBeforeChildren(), and remove all children from the scrolling node 28 before visiting state children. 29 (WebCore::ScrollingTree::removeDestroyedNodes): It was very wrong to assume 30 that all non-root nodes were parented in the root! Now we don't need to 31 remove from the parent anyway. 32 * page/scrolling/ScrollingTree.h: 33 * page/scrolling/ScrollingTreeNode.h: 34 (WebCore::ScrollingTreeNode::children): 35 1 36 2014-06-19 Simon Fraser <simon.fraser@apple.com> 2 37 -
trunk/Source/WebCore/WebCore.exp.in
r170179 r170197 2836 2836 __ZN7WebCore18ScrollingStateTree10attachNodeENS_17ScrollingNodeTypeEyy 2837 2837 __ZN7WebCore18ScrollingStateTree14stateNodeForIDEy 2838 __ZN7WebCore18ScrollingStateTree15setRemovedNodesEN3WTF 6VectorIyLm0ENS1_15CrashOnOverflowEEE2838 __ZN7WebCore18ScrollingStateTree15setRemovedNodesEN3WTF7HashSetIyNS1_7IntHashIyEENS1_10HashTraitsIyEEEE 2839 2839 __ZN7WebCore18ScrollingStateTree23setHasChangedPropertiesEb 2840 2840 __ZN7WebCore18ScrollingStateTree6commitENS_19LayerRepresentation4TypeE -
trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp
r170131 r170197 71 71 { 72 72 ASSERT(newNodeID); 73 74 73 if (ScrollingStateNode* node = stateNodeForID(newNodeID)) { 75 74 if (!parentID) … … 129 128 130 129 m_stateNodeMap.set(newNodeID, newNode); 130 m_nodesRemovedSinceLastCommit.remove(newNodeID); 131 131 return newNodeID; 132 132 } … … 210 210 void ScrollingStateTree::willRemoveNode(ScrollingStateNode* node) 211 211 { 212 m_nodesRemovedSinceLastCommit.a ppend(node->scrollingNodeID());212 m_nodesRemovedSinceLastCommit.add(node->scrollingNodeID()); 213 213 m_stateNodeMap.remove(node->scrollingNodeID()); 214 214 setHasChangedProperties(); 215 215 } 216 216 217 void ScrollingStateTree::setRemovedNodes( Vector<ScrollingNodeID> nodes)217 void ScrollingStateTree::setRemovedNodes(HashSet<ScrollingNodeID> nodes) 218 218 { 219 219 m_nodesRemovedSinceLastCommit = std::move(nodes); -
trunk/Source/WebCore/page/scrolling/ScrollingStateTree.h
r170131 r170197 57 57 void clear(); 58 58 59 const Vector<ScrollingNodeID>& removedNodes() const { return m_nodesRemovedSinceLastCommit; }60 void setRemovedNodes( Vector<ScrollingNodeID>);59 const HashSet<ScrollingNodeID>& removedNodes() const { return m_nodesRemovedSinceLastCommit; } 60 void setRemovedNodes(HashSet<ScrollingNodeID>); 61 61 62 62 // Copies the current tree state and clears the changed properties mask in the original. … … 90 90 StateNodeMap m_stateNodeMap; 91 91 RefPtr<ScrollingStateFrameScrollingNode> m_rootStateNode; 92 Vector<ScrollingNodeID> m_nodesRemovedSinceLastCommit;92 HashSet<ScrollingNodeID> m_nodesRemovedSinceLastCommit; 93 93 bool m_hasChangedProperties; 94 94 bool m_hasNewRootStateNode; -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r170196 r170197 150 150 TemporaryChange<bool> changeHandlingProgrammaticScroll(m_isHandlingProgrammaticScroll, scrollRequestIsProgammatic); 151 151 152 { 153 OrphanScrollingNodeMap orphanNodes; 154 updateTreeFromStateNode(rootNode, orphanNodes); 155 } 156 152 157 removeDestroyedNodes(*scrollingStateTree); 153 updateTreeFromStateNode(rootNode); 154 } 155 156 void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode) 158 } 159 160 void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode, OrphanScrollingNodeMap& orphanNodes) 157 161 { 158 162 if (!stateNode) { … … 162 166 } 163 167 164 // This fuction recurses through the ScrollingStateTree and updates the corresponding ScrollingTreeNodes. 165 // Find the ScrollingTreeNode associated with the current stateNode using the shared ID and our HashMap. 166 ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->scrollingNodeID()); 167 168 ScrollingTreeNode* node; 169 if (it != m_nodeMap.end()) { 168 ScrollingNodeID nodeID = stateNode->scrollingNodeID(); 169 ScrollingNodeID parentNodeID = stateNode->parentNodeID(); 170 171 auto it = m_nodeMap.find(nodeID); 172 173 RefPtr<ScrollingTreeNode> node; 174 if (it != m_nodeMap.end()) 170 175 node = it->value; 171 node->updateBeforeChildren(*stateNode); 172 } else { 173 // If the node isn't found, it's either new and needs to be added to the tree, or there is a new ID for our 174 // root node. 175 ScrollingNodeID nodeID = stateNode->scrollingNodeID(); 176 if (!stateNode->parent()) { 177 // This is the root node. Nuke the node map. 176 else { 177 node = createNode(stateNode->nodeType(), nodeID); 178 if (!parentNodeID) { 179 // This is the root node. Clear the node map. 180 ASSERT(stateNode->nodeType() == FrameScrollingNode); 181 m_rootNode = node; 178 182 m_nodeMap.clear(); 179 180 m_rootNode = createNode(FrameScrollingNode, nodeID); 181 m_nodeMap.set(nodeID, m_rootNode.get()); 182 m_rootNode->updateBeforeChildren(*stateNode); 183 node = m_rootNode.get(); 184 } else { 185 RefPtr<ScrollingTreeNode> newNode = createNode(stateNode->nodeType(), nodeID); 186 node = newNode.get(); 187 m_nodeMap.set(nodeID, node); 188 ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->parent()->scrollingNodeID()); 189 ASSERT(it != m_nodeMap.end()); 190 if (it != m_nodeMap.end()) { 191 ScrollingTreeNode* parent = it->value; 192 newNode->setParent(parent); 193 parent->appendChild(newNode.release()); 194 } 195 node->updateBeforeChildren(*stateNode); 183 } 184 m_nodeMap.set(nodeID, node.get()); 185 } 186 187 if (parentNodeID) { 188 auto parentIt = m_nodeMap.find(parentNodeID); 189 ASSERT(parentIt != m_nodeMap.end()); 190 if (parentIt != m_nodeMap.end()) { 191 ScrollingTreeNode* parent = parentIt->value; 192 node->setParent(parent); 193 parent->appendChild(node); 196 194 } 195 } 196 197 node->updateBeforeChildren(*stateNode); 198 199 // Move all children into the orphanNodes map. Live ones will get added back as we recurse over children. 200 if (auto nodeChildren = node->children()) { 201 for (auto& childScrollingNode : *nodeChildren) { 202 childScrollingNode->setParent(nullptr); 203 orphanNodes.add(childScrollingNode->scrollingNodeID(), childScrollingNode); 204 } 205 nodeChildren->clear(); 197 206 } 198 207 … … 200 209 if (auto children = stateNode->children()) { 201 210 for (auto& child : *children) 202 updateTreeFromStateNode(child.get()); 203 } 211 updateTreeFromStateNode(child.get(), orphanNodes); 212 } 213 204 214 node->updateAfterChildren(*stateNode); 205 215 } … … 215 225 clearLatchedNode(); 216 226 217 // Never destroy the root node. There will be a new root node in the state tree, and we will 218 // associate it with our existing root node in updateTreeFromStateNode(). 219 if (node->parent()) 220 m_rootNode->removeChild(node); 227 // We should have unparented this node already via updateTreeFromStateNode(). 228 ASSERT(!node->parent()); 221 229 } 222 230 } -
trunk/Source/WebCore/page/scrolling/ScrollingTree.h
r170196 r170197 132 132 private: 133 133 void removeDestroyedNodes(const ScrollingStateTree&); 134 void updateTreeFromStateNode(const ScrollingStateNode*); 134 135 typedef HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>> OrphanScrollingNodeMap; 136 void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&); 135 137 136 138 virtual PassRefPtr<ScrollingTreeNode> createNode(ScrollingNodeType, ScrollingNodeID) = 0; -
trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h
r170196 r170197 61 61 void setParent(ScrollingTreeNode* parent) { m_parent = parent; } 62 62 63 typedef Vector<RefPtr<ScrollingTreeNode>> ScrollingTreeChildrenVector; 64 ScrollingTreeChildrenVector* children() { return m_children.get(); } 65 63 66 void appendChild(PassRefPtr<ScrollingTreeNode>); 64 67 void removeChild(ScrollingTreeNode*); … … 68 71 ScrollingTree& scrollingTree() const { return m_scrollingTree; } 69 72 70 typedef Vector<RefPtr<ScrollingTreeNode>> ScrollingTreeChildrenVector;71 73 OwnPtr<ScrollingTreeChildrenVector> m_children; 72 74 -
trunk/Source/WebKit2/ChangeLog
r170196 r170197 1 2014-06-19 Simon Fraser <simon.fraser@apple.com> 2 3 Handle scrolling tree modifications which remove intermediate nodes 4 https://bugs.webkit.org/show_bug.cgi?id=134082 5 6 Reviewed by Tim Horton. 7 8 When updating the scrolling tree from the state tree, we failed to maintain 9 the children arrays correctly. Fix by removing all children on scrolling nodes, 10 and allowing the calls on children to add them back. A temporary hash map 11 keeps the nodes alive. 12 13 The state tree's m_nodesRemovedSinceLastCommit was also made into a HashSet, 14 to make it easier to handle removal followed by re-insertion. 15 16 * Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp: 17 (WebKit::RemoteScrollingCoordinatorTransaction::decode): 18 (WebKit::RemoteScrollingTreeTextStream::dump): 19 1 20 2014-06-19 Simon Fraser <simon.fraser@apple.com> 2 21 -
trunk/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp
r170118 r170197 425 425 426 426 // Removed nodes 427 Vector<ScrollingNodeID> removedNodes;427 HashSet<ScrollingNodeID> removedNodes; 428 428 if (!decoder.decode(removedNodes)) 429 429 return false; … … 684 684 recursiveDumpNodes(*stateTree.rootStateNode(), changedPropertiesOnly); 685 685 686 if (!stateTree.removedNodes().isEmpty()) 687 dumpProperty<Vector<ScrollingNodeID>>(ts, "removed-nodes", stateTree.removedNodes()); 686 if (!stateTree.removedNodes().isEmpty()) { 687 Vector<ScrollingNodeID> removedNodes; 688 copyToVector(stateTree.removedNodes(), removedNodes); 689 dumpProperty<Vector<ScrollingNodeID>>(ts, "removed-nodes", removedNodes); 690 } 688 691 } 689 692
Note:
See TracChangeset
for help on using the changeset viewer.