LibWeb: Add opt-in tracing of invalidate_layout_tree() calls with reason

This commit is contained in:
Andreas Kling 2025-03-05 21:04:20 +01:00 committed by Alexander Kalenik
parent c333042e63
commit 415079bc11
Notes: github-actions[bot] 2025-03-08 02:39:05 +00:00
8 changed files with 46 additions and 12 deletions

View file

@ -964,7 +964,7 @@ void KeyframeEffect::update_computed_properties()
if (invalidation.relayout) if (invalidation.relayout)
document.set_needs_layout(); document.set_needs_layout();
if (invalidation.rebuild_layout_tree) if (invalidation.rebuild_layout_tree)
document.invalidate_layout_tree(); document.invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::KeyframeEffect);
if (invalidation.repaint) { if (invalidation.repaint) {
document.set_needs_display(); document.set_needs_display();
document.set_needs_to_resolve_paint_only_properties(); document.set_needs_to_resolve_paint_only_properties();

View file

@ -1219,8 +1219,10 @@ void Document::set_needs_layout()
schedule_layout_update(); schedule_layout_update();
} }
void Document::invalidate_layout_tree() void Document::invalidate_layout_tree(InvalidateLayoutTreeReason reason)
{ {
if (m_layout_root)
dbgln_if(UPDATE_LAYOUT_DEBUG, "DROP TREE {}", to_string(reason));
tear_down_layout_tree(); tear_down_layout_tree();
schedule_layout_update(); schedule_layout_update();
} }
@ -3394,7 +3396,7 @@ void Document::evaluate_media_rules()
if (any_media_queries_changed_match_state) { if (any_media_queries_changed_match_state) {
style_computer().invalidate_rule_cache(); style_computer().invalidate_rule_cache();
invalidate_style(StyleInvalidationReason::MediaQueryChangedMatchState); invalidate_style(StyleInvalidationReason::MediaQueryChangedMatchState);
invalidate_layout_tree(); invalidate_layout_tree(InvalidateLayoutTreeReason::MediaQueryChangedMatchState);
} }
} }
@ -5953,7 +5955,7 @@ void Document::add_an_element_to_the_top_layer(GC::Ref<Element> element)
// FIXME: 4. At the UA !important cascade origin, add a rule targeting el containing an overlay: auto declaration. // FIXME: 4. At the UA !important cascade origin, add a rule targeting el containing an overlay: auto declaration.
element->set_rendered_in_top_layer(true); element->set_rendered_in_top_layer(true);
element->set_needs_style_update(true); element->set_needs_style_update(true);
invalidate_layout_tree(); invalidate_layout_tree(InvalidateLayoutTreeReason::DocumentAddAnElementToTheTopLayer);
} }
// https://drafts.csswg.org/css-position-4/#request-an-element-to-be-removed-from-the-top-layer // https://drafts.csswg.org/css-position-4/#request-an-element-to-be-removed-from-the-top-layer
@ -5968,7 +5970,7 @@ void Document::request_an_element_to_be_remove_from_the_top_layer(GC::Ref<Elemen
// FIXME: 3. Remove the UA !important overlay: auto rule targeting el. // FIXME: 3. Remove the UA !important overlay: auto rule targeting el.
element->set_rendered_in_top_layer(false); element->set_rendered_in_top_layer(false);
element->set_needs_style_update(true); element->set_needs_style_update(true);
invalidate_layout_tree(); invalidate_layout_tree(InvalidateLayoutTreeReason::DocumentRequestAnElementToBeRemovedFromTheTopLayer);
// 4. Append el to docs pending top layer removals. // 4. Append el to docs pending top layer removals.
m_top_layer_pending_removals.set(element); m_top_layer_pending_removals.set(element);
@ -6403,6 +6405,18 @@ void Document::set_onvisibilitychange(WebIDL::CallbackType* value)
set_event_handler_attribute(HTML::EventNames::visibilitychange, value); set_event_handler_attribute(HTML::EventNames::visibilitychange, value);
} }
StringView to_string(InvalidateLayoutTreeReason reason)
{
switch (reason) {
#define ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON(e) \
case InvalidateLayoutTreeReason::e: \
return #e##sv;
ENUMERATE_INVALIDATE_LAYOUT_TREE_REASONS(ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON)
#undef ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON
}
VERIFY_NOT_REACHED();
}
StringView to_string(UpdateLayoutReason reason) StringView to_string(UpdateLayoutReason reason)
{ {
switch (reason) { switch (reason) {

View file

@ -50,6 +50,26 @@ enum class QuirksMode {
Yes Yes
}; };
#define ENUMERATE_INVALIDATE_LAYOUT_TREE_REASONS(X) \
X(DocumentAddAnElementToTheTopLayer) \
X(DocumentRequestAnElementToBeRemovedFromTheTopLayer) \
X(HTMLInputElementSrcAttributeChange) \
X(HTMLObjectElement) \
X(KeyframeEffect) \
X(MediaQueryChangedMatchState) \
X(SVGGraphicsElementTransformAttributeChange) \
X(SVGUseElement) \
X(ShadowRootSetInnerHTML) \
X(UpdateFileInputShadowTree)
enum class InvalidateLayoutTreeReason {
#define ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON(e) e,
ENUMERATE_INVALIDATE_LAYOUT_TREE_REASONS(ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON)
#undef ENUMERATE_INVALIDATE_LAYOUT_TREE_REASON
};
[[nodiscard]] StringView to_string(InvalidateLayoutTreeReason);
#define ENUMERATE_UPDATE_LAYOUT_REASONS(X) \ #define ENUMERATE_UPDATE_LAYOUT_REASONS(X) \
X(CanvasRenderingContext2DSetFilter) \ X(CanvasRenderingContext2DSetFilter) \
X(CursorBlinkTimer) \ X(CursorBlinkTimer) \
@ -322,7 +342,7 @@ public:
void set_needs_layout(); void set_needs_layout();
void invalidate_layout_tree(); void invalidate_layout_tree(InvalidateLayoutTreeReason);
void invalidate_stacking_context_tree(); void invalidate_stacking_context_tree();
virtual bool is_child_allowed(Node const&) const override; virtual bool is_child_allowed(Node const&) const override;

View file

@ -88,7 +88,7 @@ WebIDL::ExceptionOr<void> ShadowRoot::set_inner_html(StringView value)
if (this->is_connected()) { if (this->is_connected()) {
// NOTE: Since the DOM has changed, we have to rebuild the layout tree. // NOTE: Since the DOM has changed, we have to rebuild the layout tree.
this->document().invalidate_layout_tree(); this->document().invalidate_layout_tree(InvalidateLayoutTreeReason::ShadowRootSetInnerHTML);
} }
} }

View file

@ -1129,7 +1129,7 @@ void HTMLInputElement::update_file_input_shadow_tree()
m_file_label->set_text_content(MUST(String::formatted("No {} selected.", files_label))); m_file_label->set_text_content(MUST(String::formatted("No {} selected.", files_label)));
} }
document().invalidate_layout_tree(); document().invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::UpdateFileInputShadowTree);
} }
void HTMLInputElement::create_range_input_shadow_tree() void HTMLInputElement::create_range_input_shadow_tree()
@ -1458,7 +1458,7 @@ WebIDL::ExceptionOr<void> HTMLInputElement::handle_src_attribute(String const& v
}); });
m_load_event_delayer.clear(); m_load_event_delayer.clear();
document().invalidate_layout_tree(); document().invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::HTMLInputElementSrcAttributeChange);
}, },
[this, &realm]() { [this, &realm]() {
// 2. Otherwise, if the fetching process fails without a response from the remote server, or completes but the // 2. Otherwise, if the fetching process fails without a response from the remote server, or completes but the

View file

@ -561,7 +561,7 @@ void HTMLObjectElement::update_layout_and_child_objects(Representation represent
m_representation = representation; m_representation = representation;
invalidate_style(DOM::StyleInvalidationReason::HTMLObjectElementUpdateLayoutAndChildObjects); invalidate_style(DOM::StyleInvalidationReason::HTMLObjectElementUpdateLayoutAndChildObjects);
document().invalidate_layout_tree(); document().invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::HTMLObjectElement);
} }
// https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex // https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex

View file

@ -46,7 +46,7 @@ void SVGGraphicsElement::attribute_changed(FlyString const& name, Optional<Strin
if (transform_list.has_value()) if (transform_list.has_value())
m_transform = transform_from_transform_list(*transform_list); m_transform = transform_from_transform_list(*transform_list);
// FIXME: This should only invalidate the contents of the SVG. // FIXME: This should only invalidate the contents of the SVG.
document().invalidate_layout_tree(); document().invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::SVGGraphicsElementTransformAttributeChange);
} }
} }

View file

@ -185,7 +185,7 @@ void SVGUseElement::clone_element_tree_as_our_shadow_tree(Element* to_clone)
} }
// FIXME: Only invalidate the part of the layout tree that is affected by this change. // FIXME: Only invalidate the part of the layout tree that is affected by this change.
document().invalidate_layout_tree(); document().invalidate_layout_tree(DOM::InvalidateLayoutTreeReason::SVGUseElement);
} }
bool SVGUseElement::is_valid_reference_element(Element const& reference_element) const bool SVGUseElement::is_valid_reference_element(Element const& reference_element) const