Skip to content

Commit 6307468

Browse files
committed
LibWeb: Resolve paintable containing blocks eagerly
Resolve every paintable containing block after constructing the paint tree instead of populating an optional weak cache on first access. Store the resolved relationship as a non-owning pointer and make the hot pointer accessor an inline load. Clear the pointer during relayout and detachment, and invalidate any absolute geometry cached before commit finishes resolving the relationship.
1 parent 9b7a0ea commit 6307468

4 files changed

Lines changed: 27 additions & 22 deletions

File tree

Libraries/LibWeb/Layout/LayoutState.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,19 @@ static void build_paint_tree(Node& node, Painting::Paintable* parent_paintable =
252252
build_paint_tree(*child, paintable_for_children);
253253
}
254254

255+
void LayoutState::resolve_paintable_containing_blocks(Node& root)
256+
{
257+
root.for_each_in_inclusive_subtree([](Node& node) {
258+
auto* paintable = node.paintable_ptr();
259+
if (!paintable)
260+
return TraversalDecision::Continue;
261+
262+
auto* containing_block = node.containing_block();
263+
paintable->set_containing_block(containing_block ? containing_block->paintable_ptr() : nullptr);
264+
return TraversalDecision::Continue;
265+
});
266+
}
267+
255268
void LayoutState::commit(Box& root)
256269
{
257270
if (!root.is_viewport()) {
@@ -469,6 +482,7 @@ void LayoutState::commit_used_values_and_build_paint_tree(Box& root, RefPtr<Pain
469482
});
470483

471484
build_paint_tree(root, parent_paintable.ptr(), insert_before_paintable.ptr());
485+
resolve_paintable_containing_blocks(root);
472486

473487
resolve_relative_positions();
474488

Libraries/LibWeb/Layout/LayoutState.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ struct LayoutState {
403403
[[nodiscard]] Optional<ContainedAbsposChild> take_next_contained_abspos_child(Box const& target);
404404

405405
private:
406+
void resolve_paintable_containing_blocks(Node& root);
406407
void resolve_relative_positions();
407408

408409
PagedStore<UsedValues> m_used_values_store;

Libraries/LibWeb/Painting/Paintable.cpp

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,27 +84,15 @@ DOM::Document& Paintable::document()
8484

8585
RefPtr<Paintable> Paintable::containing_block() const
8686
{
87-
return const_cast<Paintable*>(containing_block_ptr());
87+
return m_containing_block;
8888
}
8989

90-
Paintable const* Paintable::containing_block_ptr() const
90+
void Paintable::set_containing_block(Paintable* containing_block)
9191
{
92-
if (m_containing_block.has_value()) {
93-
if (auto* containing_block = m_containing_block->ptr())
94-
return containing_block;
95-
}
96-
97-
auto* containing_block = [&] -> Paintable const* {
98-
auto containing_layout_box = layout_node().containing_block();
99-
if (!containing_layout_box)
100-
return nullptr;
101-
auto* paintable_box = containing_layout_box->paintable_ptr();
102-
if (!paintable_box)
103-
return nullptr;
104-
return paintable_box;
105-
}();
92+
if (m_containing_block == containing_block)
93+
return;
10694
m_containing_block = containing_block;
107-
return containing_block;
95+
invalidate_absolute_geometry_cache(InvalidateDescendantGeometry::No);
10896
}
10997

11098
CSS::ImmutableComputedValues const& Paintable::computed_values() const
@@ -979,7 +967,7 @@ Paintable::~Paintable()
979967

980968
void Paintable::detach_from_layout_node(Badge<Layout::Node>)
981969
{
982-
m_containing_block.clear();
970+
m_containing_block = nullptr;
983971
m_layout_node.clear();
984972
detach_chrome_widgets();
985973
}
@@ -1064,7 +1052,7 @@ void Paintable::reset_for_relayout()
10641052
while (first_child())
10651053
first_child()->remove();
10661054

1067-
m_containing_block = {};
1055+
m_containing_block = nullptr;
10681056

10691057
m_offset = {};
10701058
m_content_size = {};

Libraries/LibWeb/Painting/Paintable.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class WEB_API Paintable
103103
GC::Ptr<HTML::LocalNavigable> navigable() const;
104104

105105
RefPtr<Paintable> containing_block() const;
106-
Paintable const* containing_block_ptr() const;
106+
Paintable const* containing_block_ptr() const { return m_containing_block; }
107107

108108
template<typename T>
109109
bool fast_is() const = delete;
@@ -456,9 +456,9 @@ class WEB_API Paintable
456456
CSSPixels available_scrollbar_length(ScrollDirection direction, ChromeMetrics const& chrome_metrics) const;
457457
Optional<CSSPixelRect> absolute_resizer_rect(ChromeMetrics const& chrome_metrics) const;
458458

459-
Optional<WeakPtr<Paintable>> mutable m_containing_block;
460-
461459
private:
460+
friend struct Layout::LayoutState;
461+
462462
struct CachedPaintData;
463463
enum class InvalidateDescendantGeometry {
464464
No,
@@ -467,6 +467,7 @@ class WEB_API Paintable
467467

468468
void detach_from_layout_node(Badge<Layout::Node>);
469469
void detach_chrome_widgets();
470+
void set_containing_block(Paintable* containing_block);
470471

471472
void paint_middle_button_scroll_indicator(DisplayListRecordingContext&) const;
472473
void acquire_cache_references_for_cached_commands(ReadonlyBytes) const;
@@ -475,6 +476,7 @@ class WEB_API Paintable
475476

476477
GC::Weak<DOM::Node> m_dom_node;
477478
WeakPtr<Layout::NodeWithStyleAndBoxModelMetrics const> m_layout_node;
479+
Paintable* m_containing_block { nullptr };
478480

479481
SelectionState m_selection_state { SelectionState::None };
480482

0 commit comments

Comments
 (0)