mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 01:29:17 +00:00
LibWeb: Do not mutate display list while scroll offset application
Copy a display list item and apply scroll offset instead of mutating display list directly. It's a preparation for upcoming changes where a display list will be cached across repaints and used multiple times with different scroll offsets.
This commit is contained in:
parent
7ddb94c4d6
commit
e2ad568095
Notes:
github-actions[bot]
2024-08-19 16:58:23 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: e2ad568095
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1106
3 changed files with 32 additions and 24 deletions
|
@ -2128,13 +2128,15 @@ RefPtr<Painting::DisplayList> Navigable::record_display_list(PaintConfig config)
|
||||||
|
|
||||||
viewport_paintable.paint_all_phases(context);
|
viewport_paintable.paint_all_phases(context);
|
||||||
|
|
||||||
Vector<Gfx::IntPoint> scroll_offsets_by_frame_id;
|
display_list->set_device_pixels_per_css_pixel(page.client().device_pixels_per_css_pixel());
|
||||||
scroll_offsets_by_frame_id.resize(viewport_paintable.scroll_state.size());
|
|
||||||
for (auto [_, scrollable_frame] : viewport_paintable.scroll_state) {
|
Vector<RefPtr<Painting::ScrollFrame>> scroll_state;
|
||||||
auto scroll_offset = context.rounded_device_point(scrollable_frame->cumulative_offset).to_type<int>();
|
scroll_state.resize(viewport_paintable.scroll_state.size());
|
||||||
scroll_offsets_by_frame_id[scrollable_frame->id] = scroll_offset;
|
for (auto& [_, scrollable_frame] : viewport_paintable.scroll_state) {
|
||||||
|
scroll_state[scrollable_frame->id] = scrollable_frame;
|
||||||
}
|
}
|
||||||
display_list_recorder.display_list().apply_scroll_offsets(scroll_offsets_by_frame_id);
|
|
||||||
|
display_list->set_scroll_state(move(scroll_state));
|
||||||
|
|
||||||
m_needs_repaint = false;
|
m_needs_repaint = false;
|
||||||
|
|
||||||
|
|
|
@ -24,28 +24,26 @@ static Optional<Gfx::IntRect> command_bounding_rectangle(Command const& command)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayList::apply_scroll_offsets(Vector<Gfx::IntPoint> const& offsets_by_frame_id)
|
|
||||||
{
|
|
||||||
for (auto& command_with_scroll_id : m_commands) {
|
|
||||||
if (command_with_scroll_id.scroll_frame_id.has_value()) {
|
|
||||||
auto const& scroll_frame_id = command_with_scroll_id.scroll_frame_id.value();
|
|
||||||
auto const& scroll_offset = offsets_by_frame_id[scroll_frame_id];
|
|
||||||
command_with_scroll_id.command.visit(
|
|
||||||
[&](auto& command) {
|
|
||||||
if constexpr (requires { command.translate_by(scroll_offset); })
|
|
||||||
command.translate_by(scroll_offset);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayListPlayer::execute(DisplayList& display_list)
|
void DisplayListPlayer::execute(DisplayList& display_list)
|
||||||
{
|
{
|
||||||
auto const& commands = display_list.commands();
|
auto const& commands = display_list.commands();
|
||||||
|
auto const& scroll_state = display_list.scroll_state();
|
||||||
|
auto device_pixels_per_css_pixel = display_list.device_pixels_per_css_pixel();
|
||||||
|
|
||||||
size_t next_command_index = 0;
|
size_t next_command_index = 0;
|
||||||
while (next_command_index < commands.size()) {
|
while (next_command_index < commands.size()) {
|
||||||
auto const& command = commands[next_command_index++].command;
|
auto scroll_frame_id = commands[next_command_index].scroll_frame_id;
|
||||||
|
auto command = commands[next_command_index++].command;
|
||||||
|
if (scroll_frame_id.has_value()) {
|
||||||
|
auto const& scroll_offset = scroll_state[scroll_frame_id.value()]->cumulative_offset.to_type<double>().scaled(device_pixels_per_css_pixel).to_type<int>();
|
||||||
|
command.visit(
|
||||||
|
[&](auto& command) {
|
||||||
|
if constexpr (requires { command.translate_by(scroll_offset); }) {
|
||||||
|
command.translate_by(scroll_offset);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
auto bounding_rect = command_bounding_rectangle(command);
|
auto bounding_rect = command_bounding_rectangle(command);
|
||||||
if (bounding_rect.has_value() && (bounding_rect->is_empty() || would_be_fully_clipped_by_painter(*bounding_rect))) {
|
if (bounding_rect.has_value() && (bounding_rect->is_empty() || would_be_fully_clipped_by_painter(*bounding_rect))) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <LibWeb/Painting/Command.h>
|
#include <LibWeb/Painting/Command.h>
|
||||||
#include <LibWeb/Painting/GradientData.h>
|
#include <LibWeb/Painting/GradientData.h>
|
||||||
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
#include <LibWeb/Painting/PaintBoxShadowParams.h>
|
||||||
|
#include <LibWeb/Painting/ScrollFrame.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
|
||||||
|
@ -83,8 +84,6 @@ public:
|
||||||
|
|
||||||
void append(Command&& command, Optional<i32> scroll_frame_id);
|
void append(Command&& command, Optional<i32> scroll_frame_id);
|
||||||
|
|
||||||
void apply_scroll_offsets(Vector<Gfx::IntPoint> const& offsets_by_frame_id);
|
|
||||||
|
|
||||||
struct CommandListItem {
|
struct CommandListItem {
|
||||||
Optional<i32> scroll_frame_id;
|
Optional<i32> scroll_frame_id;
|
||||||
Command command;
|
Command command;
|
||||||
|
@ -92,10 +91,19 @@ public:
|
||||||
|
|
||||||
AK::SegmentedVector<CommandListItem, 512> const& commands() const { return m_commands; }
|
AK::SegmentedVector<CommandListItem, 512> const& commands() const { return m_commands; }
|
||||||
|
|
||||||
|
void set_scroll_state(Vector<RefPtr<ScrollFrame>> scroll_state) { m_scroll_state = move(scroll_state); }
|
||||||
|
|
||||||
|
Vector<RefPtr<ScrollFrame>> const& scroll_state() const { return m_scroll_state; }
|
||||||
|
|
||||||
|
void set_device_pixels_per_css_pixel(double device_pixels_per_css_pixel) { m_device_pixels_per_css_pixel = device_pixels_per_css_pixel; }
|
||||||
|
double device_pixels_per_css_pixel() const { return m_device_pixels_per_css_pixel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DisplayList() = default;
|
DisplayList() = default;
|
||||||
|
|
||||||
AK::SegmentedVector<CommandListItem, 512> m_commands;
|
AK::SegmentedVector<CommandListItem, 512> m_commands;
|
||||||
|
Vector<RefPtr<ScrollFrame>> m_scroll_state;
|
||||||
|
double m_device_pixels_per_css_pixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue