[webkit-changes] [WebKit/WebKit] 106c4a: GraphicsLayer::removeAllChildren shouldn't be n^2
Chris Dumez
noreply at github.com
Tue Oct 3 17:36:15 PDT 2023
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 106c4aae5f4384ffb3c573f86ae4f5aa9ad0dc07
https://github.com/WebKit/WebKit/commit/106c4aae5f4384ffb3c573f86ae4f5aa9ad0dc07
Author: Chris Dumez <cdumez at apple.com>
Date: 2023-10-03 (Tue, 03 Oct 2023)
Changed paths:
M Source/WebCore/platform/graphics/GraphicsLayer.cpp
M Source/WebCore/platform/graphics/GraphicsLayer.h
M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
M Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
M Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
M Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h
M Source/WebKit/WebProcess/WebPage/wc/GraphicsLayerWC.cpp
M Source/WebKit/WebProcess/WebPage/wc/GraphicsLayerWC.h
Log Message:
-----------
GraphicsLayer::removeAllChildren shouldn't be n^2
https://bugs.webkit.org/show_bug.cgi?id=250654
rdar://104534645
Reviewed by Simon Fraser.
`GraphicsLayer::removeAllChildren()` used to select the first sublayer in the
`m_children` vector and call `removeFromParent()` on it. This would null out
`m_parent` on that sublayer and then remove the layer from m_children. This
would end up being expensive because removing items from the beginning of a
vector is expensive and involves moving following items to fill the empty
position.
To avoid the issue, I made the following changes:
1. Have GraphicsLayer::removeAllChildren() null out all parents on sub-layers
then clear m_children all at once. No more Vector::removeFirstMatching()
for each sub-layer.
2. GraphicsLayer::removeFromParent() used to be virtual, to notify the parent
layer that the children changed. However, removeFromParent() is no longer
called in removeAllChildren() after my change. To address the issue, I am
marking GraphicsLayer::removeFromParent() as non-virtual and introducing
a new GraphicsLayer::willModifyChildren() virtual function. This new
virtual gets called at the beginning of removeFromParent(), before removing
the layer from its parent, to match pre-existing behavior in child classes.
willModifyChildren() also gets called once in GraphicsLayer::removeAllChildren()
before removing all sub-layers, instead of one virtual function call per
sub-layer.
This is inspired by the following Blink change but I chose a different approach
that I believe is more optimal:
- https://chromium.googlesource.com/chromium/blink/+/ea1156d6f005f978e4da707ef4e2060c2fc7151f
* Source/WebCore/platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::removeAllChildren):
(WebCore::GraphicsLayer::removeFromParent):
* Source/WebCore/platform/graphics/GraphicsLayer.h:
(WebCore::GraphicsLayer::willModifyChildren):
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::willModifyChildren):
(WebCore::GraphicsLayerCA::removeFromParent): Deleted.
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h:
* Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
(WebCore::CoordinatedGraphicsLayer::willModifyChildren):
(WebCore::CoordinatedGraphicsLayer::removeFromParent): Deleted.
* Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
* Source/WebKit/WebProcess/WebPage/wc/GraphicsLayerWC.cpp:
(WebKit::GraphicsLayerWC::willModifyChildren):
(WebKit::GraphicsLayerWC::removeFromParent): Deleted.
* Source/WebKit/WebProcess/WebPage/wc/GraphicsLayerWC.h:
Canonical link: https://commits.webkit.org/268814@main
More information about the webkit-changes
mailing list