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

This commit is contained in:
Andreas Kling 2025-03-07 00:09:57 +01:00 committed by Alexander Kalenik
commit 2abbf99a95
Notes: github-actions[bot] 2025-03-08 02:39:00 +00:00
9 changed files with 50 additions and 12 deletions

View file

@ -146,7 +146,7 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
if (auto* layout_node = this->layout_node(); layout_node && layout_node->is_text_node())
static_cast<Layout::TextNode&>(*layout_node).invalidate_text_for_rendering();
document().set_needs_layout();
document().set_needs_layout(SetNeedsLayoutReason::CharacterDataReplaceData);
document().bump_character_data_version();
if (m_grapheme_segmenter)

View file

@ -1211,10 +1211,16 @@ Optional<String> Document::encoding_parse_and_serialize_url(StringView url) cons
return parsed_url->serialize();
}
void Document::set_needs_layout()
void Document::set_needs_layout(SetNeedsLayoutReason reason)
{
if (m_needs_layout)
return;
if constexpr (UPDATE_LAYOUT_DEBUG) {
// NOTE: We check some conditions here to avoid debug spam in documents that don't do layout.
auto navigable = this->navigable();
if (m_layout_root && navigable && navigable->active_document() == this)
dbgln_if(UPDATE_LAYOUT_DEBUG, "NEED LAYOUT {}", to_string(reason));
}
m_needs_layout = true;
schedule_layout_update();
}
@ -1527,7 +1533,7 @@ void Document::update_style()
if (!invalidation.is_none())
invalidate_display_list();
if (invalidation.relayout)
set_needs_layout();
set_needs_layout(SetNeedsLayoutReason::StyleChange);
if (invalidation.rebuild_stacking_context_tree)
invalidate_stacking_context_tree();
m_needs_full_style_update = false;
@ -6405,6 +6411,18 @@ void Document::set_onvisibilitychange(WebIDL::CallbackType* value)
set_event_handler_attribute(HTML::EventNames::visibilitychange, value);
}
StringView to_string(SetNeedsLayoutReason reason)
{
switch (reason) {
#define ENUMERATE_SET_NEEDS_LAYOUT_REASON(e) \
case SetNeedsLayoutReason::e: \
return #e##sv;
ENUMERATE_SET_NEEDS_LAYOUT_REASONS(ENUMERATE_SET_NEEDS_LAYOUT_REASON)
#undef ENUMERATE_SET_NEEDS_LAYOUT_REASON
}
VERIFY_NOT_REACHED();
}
StringView to_string(InvalidateLayoutTreeReason reason)
{
switch (reason) {

View file

@ -50,6 +50,26 @@ enum class QuirksMode {
Yes
};
#define ENUMERATE_SET_NEEDS_LAYOUT_REASONS(X) \
X(CharacterDataReplaceData) \
X(FinalizeACrossDocumentNavigation) \
X(HTMLImageElementReactToChangesInTheEnvironment) \
X(HTMLImageElementUpdateTheImageData) \
X(HTMLVideoElementSetVideoTrack) \
X(KeyframeEffect) \
X(LayoutTreeUpdate) \
X(NavigableSetViewportSize) \
X(SVGImageElementFetchTheDocument) \
X(StyleChange)
enum class SetNeedsLayoutReason {
#define ENUMERATE_SET_NEEDS_LAYOUT_REASON(e) e,
ENUMERATE_SET_NEEDS_LAYOUT_REASONS(ENUMERATE_SET_NEEDS_LAYOUT_REASON)
#undef ENUMERATE_SET_NEEDS_LAYOUT_REASON
};
[[nodiscard]] StringView to_string(SetNeedsLayoutReason);
#define ENUMERATE_INVALIDATE_LAYOUT_TREE_REASONS(X) \
X(DocumentAddAnElementToTheTopLayer) \
X(DocumentRequestAnElementToBeRemovedFromTheTopLayer) \
@ -340,7 +360,7 @@ public:
void update_paint_and_hit_testing_properties_if_needed();
void update_animated_style_if_needed();
void set_needs_layout();
void set_needs_layout(SetNeedsLayoutReason);
void invalidate_layout_tree(InvalidateLayoutTreeReason);
void invalidate_stacking_context_tree();

View file

@ -1405,7 +1405,7 @@ void Node::set_needs_layout_tree_update(bool value)
break;
ancestor->m_child_needs_layout_tree_update = true;
}
document().set_needs_layout();
document().set_needs_layout(SetNeedsLayoutReason::LayoutTreeUpdate);
}
}