Skip to content

Commit

Permalink
LibWeb: Refresh clip and scroll state only when needed
Browse files Browse the repository at this point in the history
Although refreshing is cheap, it was performed before each hit-testing
and was 2-4% in profiles on Discord and Twitter.

Now clip and scroll states are refreshed only if scroll offset has
changed.
  • Loading branch information
kalenikaliaksandr committed May 28, 2024
1 parent d6297ec commit d177021
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Userland/Libraries/LibWeb/DOM/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5056,4 +5056,16 @@ void Document::process_top_layer_removals()
}
}

void Document::set_needs_to_refresh_clip_state(bool b)
{
if (auto* paintable = this->paintable())
paintable->set_needs_to_refresh_clip_state(b);
}

void Document::set_needs_to_refresh_scroll_state(bool b)
{
if (auto* paintable = this->paintable())
paintable->set_needs_to_refresh_scroll_state(b);
}

}
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWeb/DOM/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,9 @@ class Document
bool needs_full_style_update() const { return m_needs_full_style_update; }
void set_needs_full_style_update(bool b) { m_needs_full_style_update = b; }

void set_needs_to_refresh_clip_state(bool b);
void set_needs_to_refresh_scroll_state(bool b);

bool has_active_favicon() const { return m_active_favicon; }
void check_favicon_after_loading_link_resource();

Expand Down
3 changes: 3 additions & 0 deletions Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ void PaintableBox::set_scroll_offset(CSSPixelPoint offset)
if (!scrollable_overflow_rect.has_value())
return;

document().set_needs_to_refresh_clip_state(true);
document().set_needs_to_refresh_scroll_state(true);

auto max_x_offset = scrollable_overflow_rect->width() - content_size().width();
auto max_y_offset = scrollable_overflow_rect->height() - content_size().height();
offset.set_x(clamp(offset.x(), 0, max_x_offset));
Expand Down
8 changes: 8 additions & 0 deletions Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ void ViewportPaintable::assign_clip_frames()

void ViewportPaintable::refresh_scroll_state()
{
if (!m_needs_to_refresh_scroll_state)
return;
m_needs_to_refresh_scroll_state = false;

for (auto& it : scroll_state) {
auto const& paintable_box = *it.key;
auto& scroll_frame = *it.value;
Expand All @@ -142,6 +146,10 @@ void ViewportPaintable::refresh_scroll_state()

void ViewportPaintable::refresh_clip_state()
{
if (!m_needs_to_refresh_clip_state)
return;
m_needs_to_refresh_clip_state = false;

for (auto& it : clip_state) {
auto const& paintable_box = *it.key;
auto& clip_frame = *it.value;
Expand Down
6 changes: 6 additions & 0 deletions Userland/Libraries/LibWeb/Painting/ViewportPaintable.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ class ViewportPaintable final : public PaintableWithLines {

bool handle_mousewheel(Badge<EventHandler>, CSSPixelPoint, unsigned, unsigned, int wheel_delta_x, int wheel_delta_y) override;

void set_needs_to_refresh_clip_state(bool value) { m_needs_to_refresh_clip_state = value; }
void set_needs_to_refresh_scroll_state(bool value) { m_needs_to_refresh_scroll_state = value; }

private:
void build_stacking_context_tree();

explicit ViewportPaintable(Layout::Viewport const&);

virtual void visit_edges(Visitor&) override;

bool m_needs_to_refresh_clip_state { true };
bool m_needs_to_refresh_scroll_state { true };
};

}

0 comments on commit d177021

Please sign in to comment.