Browse Source

LibWeb: Sort stacking context tree once, after fully building it

Instead of calling quick_sort() every time a StackingContext child
is added to a parent, we now do a single pass of sorting work after the
full StackingContext tree has been built.

Before this change, the quick_sort() was ~13.5% of the profile while
hovering links on GitHub in the Browser. After the change, it's down to
~0.6%. Pretty good! :^)
Andreas Kling 3 years ago
parent
commit
f5c2e87965

+ 2 - 0
Userland/Libraries/LibWeb/Layout/InitialContainingBlock.cpp

@@ -36,6 +36,8 @@ void InitialContainingBlock::build_stacking_context_tree()
         const_cast<Painting::PaintableBox*>(box.paint_box())->set_stacking_context(make<Painting::StackingContext>(box, parent_context));
         return IterationDecision::Continue;
     });
+
+    const_cast<Painting::PaintableWithLines*>(paint_box())->stacking_context()->sort();
 }
 
 void InitialContainingBlock::paint_all_phases(PaintContext& context)

+ 14 - 10
Userland/Libraries/LibWeb/Painting/StackingContext.cpp

@@ -26,18 +26,22 @@ StackingContext::StackingContext(Layout::Box& box, StackingContext* parent)
     , m_parent(parent)
 {
     VERIFY(m_parent != this);
-    if (m_parent) {
+    if (m_parent)
         m_parent->m_children.append(this);
+}
 
-        // FIXME: Don't sort on every append..
-        quick_sort(m_parent->m_children, [](auto& a, auto& b) {
-            auto a_z_index = a->m_box.computed_values().z_index().value_or(0);
-            auto b_z_index = b->m_box.computed_values().z_index().value_or(0);
-            if (a_z_index == b_z_index)
-                return a->m_box.is_before(b->m_box);
-            return a_z_index < b_z_index;
-        });
-    }
+void StackingContext::sort()
+{
+    quick_sort(m_children, [](auto& a, auto& b) {
+        auto a_z_index = a->m_box.computed_values().z_index().value_or(0);
+        auto b_z_index = b->m_box.computed_values().z_index().value_or(0);
+        if (a_z_index == b_z_index)
+            return a->m_box.is_before(b->m_box);
+        return a_z_index < b_z_index;
+    });
+
+    for (auto* child : m_children)
+        child->sort();
 }
 
 void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box, StackingContextPaintPhase phase) const

+ 2 - 0
Userland/Libraries/LibWeb/Painting/StackingContext.h

@@ -33,6 +33,8 @@ public:
 
     void dump(int indent = 0) const;
 
+    void sort();
+
 private:
     Layout::Box& m_box;
     StackingContext* const m_parent { nullptr };