Title: [295539] trunk/Source/WebCore
Revision
295539
Author
hey...@apple.com
Date
2022-06-14 14:59:59 -0700 (Tue, 14 Jun 2022)

Log Message

Track SVG renderer updates using a NodeFlag instead of on Style::Update
https://bugs.webkit.org/show_bug.cgi?id=241489
<rdar://problem/94756741>

Reviewed by Antti Koivisto.

SVG renderer updates are currently tracked as a kind of Style::Update change.
When a page is updating attributes on many SVG elements, but is not making
changes that require a restyle on those elements, we can spend a lot of time
hashing to store and look up the Style::Update associated with an element.

This patch moves the "SVG renderer update is needed" state to a Node flag
instead, but continues to use the Style::Update mechanism for root tracking,
to reduce this overhead.

This is a 1% improvement on the MotionMark Suits sub-test.

* Source/WebCore/rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::updateRenderTree):
(WebCore::RenderTreeUpdater::updateSVGRendererIfNeeded):
(WebCore::RenderTreeUpdater::updateElementRenderer):
* Source/WebCore/rendering/updating/RenderTreeUpdater.h:
* Source/WebCore/style/StyleUpdate.cpp:
(WebCore::Style::Update::addElement):
(WebCore::Style::Update::addSVGRendererUpdate):
* Source/WebCore/style/StyleUpdate.h:

Canonical link: https://commits.webkit.org/251544@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/dom/Node.h (295538 => 295539)


--- trunk/Source/WebCore/dom/Node.h	2022-06-14 21:46:28 UTC (rev 295538)
+++ trunk/Source/WebCore/dom/Node.h	2022-06-14 21:59:59 UTC (rev 295539)
@@ -235,6 +235,9 @@
     bool hasShadowRootContainingSlots() const { return hasNodeFlag(NodeFlag::HasShadowRootContainingSlots); }
     void setHasShadowRootContainingSlots(bool flag) { setNodeFlag(NodeFlag::HasShadowRootContainingSlots, flag); }
 
+    bool needsSVGRendererUpdate() const { return hasNodeFlag(NodeFlag::NeedsSVGRendererUpdate); }
+    void setNeedsSVGRendererUpdate(bool flag) { setNodeFlag(NodeFlag::NeedsSVGRendererUpdate, flag); }
+
     // If this node is in a shadow tree, returns its shadow host. Otherwise, returns null.
     WEBCORE_EXPORT Element* shadowHost() const;
     ShadowRoot* containingShadowRoot() const;
@@ -579,8 +582,9 @@
         IsComputedStyleInvalidFlag = 1 << 25,
         HasShadowRootContainingSlots = 1 << 26,
         IsInTopLayer = 1 << 27,
+        NeedsSVGRendererUpdate = 1 << 28
 
-        // Bits 28-31 are free.
+        // Bits 29-31 are free.
     };
 
     enum class TabIndexState : uint8_t {

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp (295538 => 295539)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2022-06-14 21:46:28 UTC (rev 295538)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp	2022-06-14 21:59:59 UTC (rev 295539)
@@ -173,11 +173,15 @@
 
         auto& element = downcast<Element>(node);
 
+        bool needsSVGRendererUpdate = element.needsSVGRendererUpdate();
+        if (needsSVGRendererUpdate)
+            updateSVGRenderer(element);
+
         auto* elementUpdate = m_styleUpdate->elementUpdate(element);
 
         // We hop through display: contents elements in findRenderingRoot, so
         // there may be other updates down the tree.
-        if (!elementUpdate && !element.hasDisplayContents()) {
+        if (!elementUpdate && !element.hasDisplayContents() && !needsSVGRendererUpdate) {
             storePreviousRenderer(element);
             it.traverseNextSkippingChildren();
             continue;
@@ -294,11 +298,16 @@
     m_builder.normalizeTreeAfterStyleChange(renderer, oldStyle);
 }
 
-void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdate& elementUpdate)
+void RenderTreeUpdater::updateSVGRenderer(Element& element)
 {
-    if (elementUpdate.updateSVGRenderer && element.renderer())
+    ASSERT(element.needsSVGRendererUpdate());
+    element.setNeedsSVGRendererUpdate(false);
+    if (element.renderer())
         RenderSVGResource::markForLayoutAndParentResourceInvalidation(*element.renderer());
+}
 
+void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdate& elementUpdate)
+{
     if (!elementUpdate.style)
         return;
 

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h (295538 => 295539)


--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h	2022-06-14 21:46:28 UTC (rev 295538)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdater.h	2022-06-14 21:59:59 UTC (rev 295539)
@@ -59,6 +59,7 @@
     void updateTextRenderer(Text&, const Style::TextUpdate*);
     void createTextRenderer(Text&, const Style::TextUpdate*);
     void updateElementRenderer(Element&, const Style::ElementUpdate&);
+    void updateSVGRenderer(Element&);
     void updateRendererStyle(RenderElement&, RenderStyle&&, StyleDifference);
     void createRenderer(Element&, RenderStyle&&);
     void updateBeforeDescendants(Element&, const Style::ElementUpdate*);

Modified: trunk/Source/WebCore/style/StyleUpdate.cpp (295538 => 295539)


--- trunk/Source/WebCore/style/StyleUpdate.cpp	2022-06-14 21:46:28 UTC (rev 295538)
+++ trunk/Source/WebCore/style/StyleUpdate.cpp	2022-06-14 21:59:59 UTC (rev 295539)
@@ -89,18 +89,12 @@
 void Update::addElement(Element& element, Element* parent, ElementUpdate&& elementUpdate)
 {
     ASSERT(composedTreeAncestors(element).first() == parent);
+    ASSERT(!m_elements.contains(&element));
 
     m_roots.remove(&element);
     addPossibleRoot(parent);
 
-    auto result = m_elements.add(&element, WTFMove(elementUpdate));
-
-    if (!result.isNewEntry) {
-        auto& entry = result.iterator->value;
-        ASSERT(entry.updateSVGRenderer);
-        entry = WTFMove(elementUpdate);
-        entry.updateSVGRenderer = true;
-    }
+    m_elements.add(&element, WTFMove(elementUpdate));
 }
 
 void Update::addText(Text& text, Element* parent, TextUpdate&& textUpdate)
@@ -131,9 +125,10 @@
 
 void Update::addSVGRendererUpdate(SVGElement& element)
 {
-    auto elementUpdate = ElementUpdate { };
-    elementUpdate.updateSVGRenderer = true;
-    addElement(element, composedTreeAncestors(element).first(), WTFMove(elementUpdate));
+    auto parent = composedTreeAncestors(element).first();
+    m_roots.remove(&element);
+    addPossibleRoot(parent);
+    element.setNeedsSVGRendererUpdate(true);
 }
 
 void Update::addPossibleRoot(Element* element)
@@ -142,7 +137,7 @@
         m_roots.add(m_document.ptr());
         return;
     }
-    if (m_elements.contains(element))
+    if (element->needsSVGRendererUpdate() || m_elements.contains(element))
         return;
     m_roots.add(element);
 }

Modified: trunk/Source/WebCore/style/StyleUpdate.h (295538 => 295539)


--- trunk/Source/WebCore/style/StyleUpdate.h	2022-06-14 21:46:28 UTC (rev 295538)
+++ trunk/Source/WebCore/style/StyleUpdate.h	2022-06-14 21:59:59 UTC (rev 295539)
@@ -46,7 +46,6 @@
     std::unique_ptr<RenderStyle> style;
     Change change { Change::None };
     bool recompositeLayer { false };
-    bool updateSVGRenderer { false };
 };
 
 struct TextUpdate {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to