Title: [131804] trunk/Source/WebCore
Revision
131804
Author
bda...@apple.com
Date
2012-10-18 14:25:35 -0700 (Thu, 18 Oct 2012)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=99668
REGRESSION: Crash in 
WebCore::ScrollingStateScrollingNode::setNonFastScrollableRegion
-and corresponding-
<rdar://problem/12491901>

Reviewed by Simon Fraser.

http://trac.webkit.org/changeset/130783 changed the lifetime of the 
ScrollingStateTree's rootStateNode. Before that patch, the root state 
node was never destroyed. It was just constantly re-used for 
different RenderLayerBackings. This crash is just one of a few bugs 
that has occurred because of that change. I have fixed the other bugs 
individually, but I think that long-term, it is the safest solution 
to go back to the original ownership model.

So this patch ensures that the state tree will always have a root 
state node. Instead of destroying and re-creating the root node when 
it's scroll ID changes, we just update the ID.

attachToStateTree() now takes an additional ID representing the ID of 
the parent node.
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::attachToStateTree):

Add a way to set the scrolling node ID.
* page/scrolling/ScrollingStateNode.h:
(WebCore::ScrollingStateNode::setScrollingNodeID):

This code that provided a way to mark all properties as having 
changed was added in http://trac.webkit.org/changeset/130989 as a way 
to ensure we would re-set ScrollingThread's nodes when we destroyed 
and re-created the rootStateNode. Now that we are no longer 
destroying and re-creating the rootStateNode, this code is no longer 
necessary.
* page/scrolling/ScrollingStateScrollingNode.cpp:
* page/scrolling/ScrollingStateScrollingNode.h:

create m_rootStateNode right in the ScrollingStateTree's constructor.
* page/scrolling/ScrollingStateTree.cpp:
(WebCore::ScrollingStateTree::ScrollingStateTree):

Don't let removeNode() destroy m_rootStateNode.
(WebCore::ScrollingStateTree::removeNode):

Also a part of r130989 that is no longer needed.
(WebCore::ScrollingStateTree::rootLayerDidChange():
* page/scrolling/ScrollingStateTree.h:
(WebCore::ScrollingStateTree::rootStateNode):
(ScrollingStateTree):
(WebCore::ScrollingStateTree::setRootStateNode):

attachToStateTree() now takes an additional ID representing the ID of 
the parent node.
* page/scrolling/mac/ScrollingCoordinatorMac.h:
(ScrollingCoordinatorMac):

We no longer need ScrollingStateTree::rootLayerDidChange()
* page/scrolling/mac/ScrollingCoordinatorMac.mm:
(WebCore::ScrollingCoordinatorMac::frameViewRootLayerDidChange):

Do not destroy and re-create the state node. Just update its ID. When 
we support child nodes soon, we will create them in this function.
(WebCore::ScrollingCoordinatorMac::attachToStateTree):

No need to null-check the rootStateNode.
(WebCore::ScrollingCoordinatorMac::clearStateTree):

Send 0 as the parent node ID to attachToStateTree() to represent the 
root node.
(WebCore::ScrollingCoordinatorMac::ensureRootStateNodeForFrameView):
* rendering/RenderLayerBacking.cpp:

RenderLayerBacking::attachToScrollingCoordinator() now takes a parent 
layer.
(WebCore::RenderLayerBacking::attachToScrollingCoordinator):
* rendering/RenderLayerBacking.h:
(RenderLayerBacking):

Since this is the root, send 0 to represent the parent layer.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateBacking):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (131803 => 131804)


--- trunk/Source/WebCore/ChangeLog	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/ChangeLog	2012-10-18 21:25:35 UTC (rev 131804)
@@ -1,3 +1,88 @@
+2012-10-18  Beth Dakin  <bda...@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=99668
+        REGRESSION: Crash in 
+        WebCore::ScrollingStateScrollingNode::setNonFastScrollableRegion
+        -and corresponding-
+        <rdar://problem/12491901>
+
+        Reviewed by Simon Fraser.
+
+        http://trac.webkit.org/changeset/130783 changed the lifetime of the 
+        ScrollingStateTree's rootStateNode. Before that patch, the root state 
+        node was never destroyed. It was just constantly re-used for 
+        different RenderLayerBackings. This crash is just one of a few bugs 
+        that has occurred because of that change. I have fixed the other bugs 
+        individually, but I think that long-term, it is the safest solution 
+        to go back to the original ownership model.
+
+        So this patch ensures that the state tree will always have a root 
+        state node. Instead of destroying and re-creating the root node when 
+        it's scroll ID changes, we just update the ID.
+
+        attachToStateTree() now takes an additional ID representing the ID of 
+        the parent node.
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::attachToStateTree):
+
+        Add a way to set the scrolling node ID.
+        * page/scrolling/ScrollingStateNode.h:
+        (WebCore::ScrollingStateNode::setScrollingNodeID):
+
+        This code that provided a way to mark all properties as having 
+        changed was added in http://trac.webkit.org/changeset/130989 as a way 
+        to ensure we would re-set ScrollingThread's nodes when we destroyed 
+        and re-created the rootStateNode. Now that we are no longer 
+        destroying and re-creating the rootStateNode, this code is no longer 
+        necessary.
+        * page/scrolling/ScrollingStateScrollingNode.cpp:
+        * page/scrolling/ScrollingStateScrollingNode.h:
+
+        create m_rootStateNode right in the ScrollingStateTree's constructor.
+        * page/scrolling/ScrollingStateTree.cpp:
+        (WebCore::ScrollingStateTree::ScrollingStateTree):
+
+        Don't let removeNode() destroy m_rootStateNode.
+        (WebCore::ScrollingStateTree::removeNode):
+
+        Also a part of r130989 that is no longer needed.
+        (WebCore::ScrollingStateTree::rootLayerDidChange():
+        * page/scrolling/ScrollingStateTree.h:
+        (WebCore::ScrollingStateTree::rootStateNode):
+        (ScrollingStateTree):
+        (WebCore::ScrollingStateTree::setRootStateNode):
+
+        attachToStateTree() now takes an additional ID representing the ID of 
+        the parent node.
+        * page/scrolling/mac/ScrollingCoordinatorMac.h:
+        (ScrollingCoordinatorMac):
+
+        We no longer need ScrollingStateTree::rootLayerDidChange()
+        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
+        (WebCore::ScrollingCoordinatorMac::frameViewRootLayerDidChange):
+
+        Do not destroy and re-create the state node. Just update its ID. When 
+        we support child nodes soon, we will create them in this function.
+        (WebCore::ScrollingCoordinatorMac::attachToStateTree):
+
+        No need to null-check the rootStateNode.
+        (WebCore::ScrollingCoordinatorMac::clearStateTree):
+
+        Send 0 as the parent node ID to attachToStateTree() to represent the 
+        root node.
+        (WebCore::ScrollingCoordinatorMac::ensureRootStateNodeForFrameView):
+        * rendering/RenderLayerBacking.cpp:
+
+        RenderLayerBacking::attachToScrollingCoordinator() now takes a parent 
+        layer.
+        (WebCore::RenderLayerBacking::attachToScrollingCoordinator):
+        * rendering/RenderLayerBacking.h:
+        (RenderLayerBacking):
+
+        Since this is the root, send 0 to represent the parent layer.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateBacking):
+
 2012-10-18  Yael Aharon  <yael.aha...@intel.com>
 
         [EFL] GraphicsContext3D::m_renderStyle is not initialized

Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -109,7 +109,7 @@
     virtual bool requestScrollPositionUpdate(FrameView*, const IntPoint&) { return false; }
     virtual bool handleWheelEvent(FrameView*, const PlatformWheelEvent&) { return true; }
     virtual void updateMainFrameScrollPositionAndScrollLayerPosition() { }
-    virtual ScrollingNodeID attachToStateTree(ScrollingNodeID nodeID) { return nodeID; }
+    virtual ScrollingNodeID attachToStateTree(ScrollingNodeID newNodeID, ScrollingNodeID /*parentID*/) { return newNodeID; }
     virtual void detachFromStateTree(ScrollingNodeID) { }
     virtual void clearStateTree() { }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateNode.h (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateNode.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateNode.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -71,6 +71,7 @@
     void setScrollingStateTree(ScrollingStateTree* tree) { m_scrollingStateTree = tree; }
 
     ScrollingNodeID scrollingNodeID() const { return m_nodeID; }
+    void setScrollingNodeID(ScrollingNodeID nodeID) { m_nodeID = nodeID; }
 
     ScrollingStateNode* parent() const { return m_parent; }
     void setParent(ScrollingStateNode* parent) { m_parent = parent; }

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp	2012-10-18 21:25:35 UTC (rev 131804)
@@ -77,12 +77,6 @@
 {
 }
 
-void ScrollingStateScrollingNode::setHasChangedProperties()
-{
-    m_changedProperties = All;
-    ScrollingStateNode::setHasChangedProperties();
-}
-
 PassOwnPtr<ScrollingStateNode> ScrollingStateScrollingNode::cloneAndResetNode()
 {
     OwnPtr<ScrollingStateScrollingNode> clone = adoptPtr(new ScrollingStateScrollingNode(this));

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -56,7 +56,6 @@
         VerticalScrollbarMode = 1 << 10,
         ScrollOrigin = 1 << 11,
         RequestedScrollPosition = 1 << 12,
-        All = (1 << 13) - 1 // This will need to be updated if we add or remove anything the ChangedProperties.
     };
 
     virtual bool isScrollingStateScrollingNode() OVERRIDE { return true; }
@@ -66,7 +65,6 @@
     virtual bool hasChangedProperties() const OVERRIDE { return m_changedProperties; }
     virtual unsigned changedProperties() const OVERRIDE { return m_changedProperties; }
     virtual void resetChangedProperties() OVERRIDE { m_changedProperties = 0; }
-    virtual void setHasChangedProperties();
 
     const IntRect& viewportRect() const { return m_viewportRect; }
     void setViewportRect(const IntRect&);

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2012-10-18 21:25:35 UTC (rev 131804)
@@ -36,7 +36,8 @@
 }
 
 ScrollingStateTree::ScrollingStateTree()
-    : m_hasChangedProperties(false)
+    : m_rootStateNode(ScrollingStateScrollingNode::create(this, 0))
+    , m_hasChangedProperties(false)
 {
 }
 
@@ -63,13 +64,6 @@
 void ScrollingStateTree::removeNode(ScrollingStateNode* node)
 {
     ASSERT(m_rootStateNode);
-
-    if (node == m_rootStateNode) {
-        didRemoveNode(m_rootStateNode->scrollingNodeID());
-        m_rootStateNode = 0;
-        return;
-    }
-
     m_rootStateNode->removeChild(node);
 }
 
@@ -78,16 +72,6 @@
     m_nodesRemovedSinceLastCommit.append(nodeID);
 }
 
-void ScrollingStateTree::rootLayerDidChange()
-{
-    // If the root layer has changed, then destroyed and re-created the root state node. That means that the
-    // cached properties in ScrollingStateScrollingNode are no longer reflective of the properties we have
-    // cached over in the ScrollingTree. To resolve this, we will mark all of the properties as having changed
-    // so that the ScrollingTree will be in synch with the state tree.
-    setHasChangedProperties(true);
-    rootStateNode()->setHasChangedProperties();
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(THREADED_SCROLLING)

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateTree.h (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateTree.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateTree.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -55,7 +55,6 @@
     ~ScrollingStateTree();
 
     ScrollingStateScrollingNode* rootStateNode() const { return m_rootStateNode.get(); }
-    void setRootStateNode(PassOwnPtr<ScrollingStateScrollingNode> rootStateNode) { m_rootStateNode = rootStateNode; }
 
     // Copies the current tree state and clears the changed properties mask in the original.
     PassOwnPtr<ScrollingStateTree> commit();
@@ -64,14 +63,14 @@
     void didRemoveNode(ScrollingNodeID);
     const Vector<ScrollingNodeID>& removedNodes() const { return m_nodesRemovedSinceLastCommit; }
 
-    void rootLayerDidChange();
-
     void setHasChangedProperties(bool changedProperties) { m_hasChangedProperties = changedProperties; }
     bool hasChangedProperties() const { return m_hasChangedProperties; }
 
 private:
     ScrollingStateTree();
 
+    void setRootStateNode(PassOwnPtr<ScrollingStateScrollingNode> rootStateNode) { m_rootStateNode = rootStateNode; }
+
     PassOwnPtr<ScrollingStateTree> clone();
 
     OwnPtr<ScrollingStateScrollingNode> m_rootStateNode;

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -66,7 +66,7 @@
 
     // These functions are used to indicate that a layer should be (or should not longer be) represented by a node
     // in the scrolling tree.
-    virtual ScrollingNodeID attachToStateTree(ScrollingNodeID);
+    virtual ScrollingNodeID attachToStateTree(ScrollingNodeID newNodeID, ScrollingNodeID parentID);
     virtual void detachFromStateTree(ScrollingNodeID);
 
     // This function wipes out the current tree.

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm (131803 => 131804)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm	2012-10-18 21:25:35 UTC (rev 131804)
@@ -147,7 +147,6 @@
     // If the root layer does not have a ScrollingStateNode, then we should create one.
     ensureRootStateNodeForFrameView(frameView);
     ASSERT(m_scrollingStateTree->rootStateNode());
-    m_scrollingStateTree->rootLayerDidChange();
 
     ScrollingCoordinator::frameViewRootLayerDidChange(frameView);
 
@@ -234,22 +233,26 @@
         scrollLayer->setPosition(-frameView->scrollPosition());
 }
 
-ScrollingNodeID ScrollingCoordinatorMac::attachToStateTree(ScrollingNodeID scrollLayerID)
+ScrollingNodeID ScrollingCoordinatorMac::attachToStateTree(ScrollingNodeID newNodeID, ScrollingNodeID parentID)
 {
-    ASSERT(scrollLayerID);
+    ASSERT(newNodeID);
 
-    ScrollingStateScrollingNode* existingNode = stateNodeForID(scrollLayerID);
+    ScrollingStateScrollingNode* existingNode = stateNodeForID(newNodeID);
     if (existingNode && existingNode == m_scrollingStateTree->rootStateNode())
-        return scrollLayerID;
+        return newNodeID;
 
-    clearStateTree();
+    // If there is no parent, this is the root node. Right now, we only support the root node.
+    // FIXME: In the future, we should append child nodes in the appropriate spot in the state
+    // tree.
+    if (!parentID) {
+        // If we're resetting the root node, we should clear the HashMap and destroy the current children.
+        clearStateTree();
 
-    // FIXME: In the future, this function will have to take a parent ID so that it can
-    // append the node in the appropriate spot in the state tree. For now we always assume
-    // this is the root node.
-    m_scrollingStateTree->setRootStateNode(ScrollingStateScrollingNode::create(m_scrollingStateTree.get(), scrollLayerID));
-    m_stateNodeMap.set(scrollLayerID, m_scrollingStateTree->rootStateNode());
-    return scrollLayerID;
+        m_scrollingStateTree->rootStateNode()->setScrollingNodeID(newNodeID);
+        m_stateNodeMap.set(newNodeID, m_scrollingStateTree->rootStateNode());
+    }
+
+    return newNodeID;
 }
 
 void ScrollingCoordinatorMac::detachFromStateTree(ScrollingNodeID scrollLayerID)
@@ -275,8 +278,7 @@
 void ScrollingCoordinatorMac::clearStateTree()
 {
     m_stateNodeMap.clear();
-    if (ScrollingStateScrollingNode* node = m_scrollingStateTree->rootStateNode())
-        m_scrollingStateTree->removeNode(node);
+    m_scrollingStateTree->removeNode(m_scrollingStateTree->rootStateNode());
 }
 
 ScrollingStateScrollingNode* ScrollingCoordinatorMac::stateNodeForID(ScrollingNodeID scrollLayerID)
@@ -294,7 +296,7 @@
 
 void ScrollingCoordinatorMac::ensureRootStateNodeForFrameView(FrameView* frameView)
 {
-    attachToStateTree(frameView->scrollLayerID());
+    attachToStateTree(frameView->scrollLayerID(), 0);
 }
 
 void ScrollingCoordinatorMac::setScrollLayerForNode(GraphicsLayer* scrollLayer, ScrollingStateNode* node)

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (131803 => 131804)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2012-10-18 21:25:35 UTC (rev 131804)
@@ -965,7 +965,7 @@
     return layerChanged;
 }
 
-void RenderLayerBacking::attachToScrollingCoordinator()
+void RenderLayerBacking::attachToScrollingCoordinator(RenderLayerBacking* parent)
 {
     // If m_scrollLayerID non-zero, then this backing is already attached to the ScrollingCoordinator.
     if (m_scrollLayerID)
@@ -978,8 +978,9 @@
     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
     if (!scrollingCoordinator)
         return;
-    
-    m_scrollLayerID = scrollingCoordinator->attachToStateTree(scrollingCoordinator->uniqueScrollLayerID());
+
+    ScrollingNodeID parentID = parent ? parent->scrollLayerID() : 0;
+    m_scrollLayerID = scrollingCoordinator->attachToStateTree(scrollingCoordinator->uniqueScrollLayerID(), parentID);
 }
 
 void RenderLayerBacking::detachFromScrollingCoordinator()

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (131803 => 131804)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2012-10-18 21:25:35 UTC (rev 131804)
@@ -88,7 +88,7 @@
     GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
     GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
 
-    void attachToScrollingCoordinator();
+    void attachToScrollingCoordinator(RenderLayerBacking* parent);
     uint64_t scrollLayerID() const { return m_scrollLayerID; }
     
     bool hasMaskLayer() const { return m_maskLayer != 0; }

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (131803 => 131804)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-10-18 21:21:41 UTC (rev 131803)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2012-10-18 21:25:35 UTC (rev 131804)
@@ -510,7 +510,7 @@
 
             // At this time, the ScrollingCooridnator only supports the top-level frame.
             if (layer->isRootLayer() && !m_renderView->document()->ownerElement()) {
-                layer->backing()->attachToScrollingCoordinator();
+                layer->backing()->attachToScrollingCoordinator(0);
                 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
                     scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
             }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to