Skip to content

Commit

Permalink
LibWeb: Use stack to represent blit/sample corners commands state
Browse files Browse the repository at this point in the history
...instead of allocating separate BorderRadiusCornerClipper for each
executed sample/blit commands pair.

With this change a vector of BorderRadiusCornerClipper has far fewer
items. For example on twitter profile page its size goes down from
~3000 to ~3 items.
  • Loading branch information
kalenikaliaksandr authored and awesomekling committed May 27, 2024
1 parent 9b65a27 commit 0eeae7f
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 14 deletions.
20 changes: 11 additions & 9 deletions Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,21 +453,23 @@ CommandResult CommandExecutorCPU::draw_triangle_wave(Gfx::IntPoint const& p1, Gf
return CommandResult::Continue;
}

CommandResult CommandExecutorCPU::sample_under_corners(u32 id, CornerRadii const& corner_radii, Gfx::IntRect const& border_rect, CornerClip corner_clip)
void CommandExecutorCPU::prepare_to_execute(size_t corner_clip_max_depth)
{
if (id >= m_corner_clippers.size())
m_corner_clippers.resize(id + 1);
m_corner_clippers_stack.ensure_capacity(corner_clip_max_depth);
}

auto clipper = BorderRadiusCornerClipper::create(corner_radii, border_rect.to_type<DevicePixels>(), corner_clip);
m_corner_clippers[id] = clipper.release_value();
m_corner_clippers[id]->sample_under_corners(painter());
CommandResult CommandExecutorCPU::sample_under_corners([[maybe_unused]] u32 id, CornerRadii const& corner_radii, Gfx::IntRect const& border_rect, CornerClip corner_clip)
{
auto clipper = BorderRadiusCornerClipper::create(corner_radii, border_rect.to_type<DevicePixels>(), corner_clip).release_value();
clipper->sample_under_corners(painter());
m_corner_clippers_stack.append(clipper);
return CommandResult::Continue;
}

CommandResult CommandExecutorCPU::blit_corner_clipping(u32 id)
CommandResult CommandExecutorCPU::blit_corner_clipping([[maybe_unused]] u32 id)
{
m_corner_clippers[id]->blit_corner_clipping(painter());
m_corner_clippers[id] = nullptr;
auto clipper = m_corner_clippers_stack.take_last();
clipper->blit_corner_clipping(painter());
return CommandResult::Continue;
}

Expand Down
4 changes: 3 additions & 1 deletion Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ class CommandExecutorCPU : public CommandExecutor {
bool needs_prepare_glyphs_texture() const override { return false; }
void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const&) override {};

virtual void prepare_to_execute(size_t corner_clip_max_depth) override;

bool needs_update_immutable_bitmap_texture_cache() const override { return false; }
void update_immutable_bitmap_texture_cache(HashMap<u32, Gfx::ImmutableBitmap const*>&) override {};

CommandExecutorCPU(Gfx::Bitmap& bitmap);

private:
Gfx::Bitmap& m_target_bitmap;
Vector<RefPtr<BorderRadiusCornerClipper>> m_corner_clippers;
Vector<RefPtr<BorderRadiusCornerClipper>> m_corner_clippers_stack;

struct StackingContext {
MaybeOwned<Gfx::Painter> painter;
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ void CommandExecutorGPU::prepare_glyph_texture(HashMap<Gfx::Font const*, HashTab
AccelGfx::GlyphAtlas::the().update(unique_glyphs);
}

void CommandExecutorGPU::prepare_to_execute()
void CommandExecutorGPU::prepare_to_execute([[maybe_unused]] size_t corner_clip_max_depth)
{
m_context.activate();
}
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/Painting/CommandExecutorGPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CommandExecutorGPU : public CommandExecutor {
virtual bool needs_prepare_glyphs_texture() const override { return true; }
void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const&) override;

virtual void prepare_to_execute() override;
virtual void prepare_to_execute(size_t corner_clip_max_depth) override;

bool needs_update_immutable_bitmap_texture_cache() const override { return true; }
void update_immutable_bitmap_texture_cache(HashMap<u32, Gfx::ImmutableBitmap const*>&) override;
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibWeb/Painting/CommandList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void CommandList::mark_unnecessary_commands()

void CommandList::execute(CommandExecutor& executor)
{
executor.prepare_to_execute();
executor.prepare_to_execute(m_corner_clip_max_depth);

if (executor.needs_prepare_glyphs_texture()) {
HashMap<Gfx::Font const*, HashTable<u32>> unique_glyphs;
Expand Down
6 changes: 5 additions & 1 deletion Userland/Libraries/LibWeb/Painting/CommandList.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class CommandExecutor {
virtual bool would_be_fully_clipped_by_painter(Gfx::IntRect) const = 0;
virtual bool needs_prepare_glyphs_texture() const { return false; }
virtual void prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const& unique_glyphs) = 0;
virtual void prepare_to_execute() { }
virtual void prepare_to_execute([[maybe_unused]] size_t corner_clip_max_depth) { }
virtual bool needs_update_immutable_bitmap_texture_cache() const = 0;
virtual void update_immutable_bitmap_texture_cache(HashMap<u32, Gfx::ImmutableBitmap const*>&) = 0;
};
Expand All @@ -99,13 +99,17 @@ class CommandList {
void mark_unnecessary_commands();
void execute(CommandExecutor&);

size_t corner_clip_max_depth() const { return m_corner_clip_max_depth; }
void set_corner_clip_max_depth(size_t depth) { m_corner_clip_max_depth = depth; }

private:
struct CommandListItem {
Optional<i32> scroll_frame_id;
Command command;
bool skip { false };
};

size_t m_corner_clip_max_depth { 0 };
AK::SegmentedVector<CommandListItem, 512> m_commands;
};

Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void RecordingPainter::append(Command&& command)
void RecordingPainter::sample_under_corners(u32 id, CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip)
{
m_corner_clip_state_stack.append({ id, border_rect });
if (m_corner_clip_state_stack.size() > commands_list().corner_clip_max_depth())
commands_list().set_corner_clip_max_depth(m_corner_clip_state_stack.size());
append(SampleUnderCorners {
id,
corner_radii,
Expand Down

0 comments on commit 0eeae7f

Please sign in to comment.