LibWeb/Painting: Remove Save and Restore commands in RecordingPainter

Removing State and Restore reduces painting commands count by 30-50%
on an average website.

Due to this change, it was also necessary to replace AddClipRect with
SetClipRect command.
This commit is contained in:
Aliaksandr Kalenik 2023-10-26 04:12:57 +02:00 committed by Andreas Kling
parent 0388766531
commit 04a4ffaa3d
Notes: sideshowbarker 2024-07-17 04:34:25 +09:00
2 changed files with 22 additions and 35 deletions

View file

@ -123,23 +123,10 @@ CommandResult DrawScaledBitmap::execute(CommandExecutionState& state) const
return CommandResult::Continue;
}
CommandResult SaveState::execute(CommandExecutionState& state) const
{
auto& painter = state.painter();
painter.save();
return CommandResult::Continue;
}
CommandResult RestoreState::execute(CommandExecutionState& state) const
{
auto& painter = state.painter();
painter.restore();
return CommandResult::Continue;
}
CommandResult AddClipRect::execute(CommandExecutionState& state) const
CommandResult SetClipRect::execute(CommandExecutionState& state) const
{
auto& painter = state.painter();
painter.clear_clip_rect();
painter.add_clip_rect(rect);
return CommandResult::Continue;
}
@ -648,12 +635,15 @@ void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Utf8View stri
void RecordingPainter::add_clip_rect(Gfx::IntRect const& rect)
{
push_command(AddClipRect { .rect = state().translation.map(rect) });
}
auto prev_clip_rect = state().clip_rect;
if (!state().clip_rect.has_value()) {
state().clip_rect = state().translation.map(rect);
} else {
state().clip_rect->intersect(state().translation.map(rect));
}
void RecordingPainter::clear_clip_rect()
{
push_command(ClearClipRect {});
if (prev_clip_rect != state().clip_rect)
push_command(SetClipRect { .rect = *state().clip_rect });
}
void RecordingPainter::translate(int dx, int dy)
@ -674,14 +664,21 @@ void RecordingPainter::set_font(Gfx::Font const& font)
void RecordingPainter::save()
{
m_state_stack.append(m_state_stack.last());
push_command(SaveState {});
}
void RecordingPainter::restore()
{
auto prev_clip_rect = state().clip_rect;
VERIFY(m_state_stack.size() > 1);
m_state_stack.take_last();
push_command(RestoreState {});
if (state().clip_rect != prev_clip_rect) {
if (state().clip_rect.has_value())
push_command(SetClipRect { .rect = *state().clip_rect });
else
push_command(ClearClipRect {});
}
}
void RecordingPainter::push_stacking_context(PushStackingContextParams params)

View file

@ -83,15 +83,7 @@ struct DrawScaledBitmap {
[[nodiscard]] CommandResult execute(CommandExecutionState&) const;
};
struct SaveState {
[[nodiscard]] CommandResult execute(CommandExecutionState&) const;
};
struct RestoreState {
[[nodiscard]] CommandResult execute(CommandExecutionState&) const;
};
struct AddClipRect {
struct SetClipRect {
Gfx::IntRect rect;
[[nodiscard]] CommandResult execute(CommandExecutionState&) const;
@ -361,9 +353,7 @@ using PaintingCommand = Variant<
DrawText,
FillRect,
DrawScaledBitmap,
SaveState,
RestoreState,
AddClipRect,
SetClipRect,
ClearClipRect,
SetFont,
PushStackingContext,
@ -454,7 +444,6 @@ public:
void draw_text_run(Gfx::IntPoint baseline_start, Utf8View string, Gfx::Font const& font, Color color, Gfx::IntRect const& rect);
void add_clip_rect(Gfx::IntRect const& rect);
void clear_clip_rect();
void translate(int dx, int dy);
void translate(Gfx::IntPoint delta);
@ -510,6 +499,7 @@ public:
struct State {
Gfx::AffineTransform translation;
Optional<Gfx::IntRect> clip_rect;
};
State& state() { return m_state_stack.last(); }
State const& state() const { return m_state_stack.last(); }