From e8b7c88881c099ffdd23265719588f97c766ba0c Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Wed, 24 Jul 2024 16:48:32 +0300 Subject: [PATCH] LibWeb: Move display list command dispatch into player With this change display list player will be able to recurse into executing another display list, without having to construct new display list player. It is going to be useful in the upcoming changes to paint a mask from a display list owned by a command. --- .../LibWeb/HTML/TraversableNavigable.cpp | 8 ++--- .../Libraries/LibWeb/Painting/DisplayList.cpp | 18 ++++++----- .../Libraries/LibWeb/Painting/DisplayList.h | 10 +++++-- .../LibWeb/Painting/DisplayListPlayerSkia.h | 30 +++++++++---------- .../Libraries/LibWeb/Painting/SVGMaskable.cpp | 4 +-- .../LibWeb/SVG/SVGDecodedImageData.cpp | 4 +-- 6 files changed, 41 insertions(+), 33 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index 840bf33f978..98b8dcba2b2 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -1209,7 +1209,7 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting:: auto& iosurface_backing_store = static_cast(target); auto texture = m_metal_context->create_texture_from_iosurface(iosurface_backing_store.iosurface_handle()); Painting::DisplayListPlayerSkia player(*m_skia_backend_context, *texture); - display_list.execute(player); + player.execute(display_list); return; } #endif @@ -1217,19 +1217,19 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting:: #ifdef USE_VULKAN if (m_skia_backend_context) { Painting::DisplayListPlayerSkia player(*m_skia_backend_context, target.bitmap()); - display_list.execute(player); + player.execute(display_list); return; } #endif // Fallback to CPU backend if GPU is not available Painting::DisplayListPlayerSkia player(target.bitmap()); - display_list.execute(player); + player.execute(display_list); break; } case DisplayListPlayerType::SkiaCPU: { Painting::DisplayListPlayerSkia player(target.bitmap()); - display_list.execute(player); + player.execute(display_list); break; } default: diff --git a/Userland/Libraries/LibWeb/Painting/DisplayList.cpp b/Userland/Libraries/LibWeb/Painting/DisplayList.cpp index f4bb778e808..dcc9d3bd2ef 100644 --- a/Userland/Libraries/LibWeb/Painting/DisplayList.cpp +++ b/Userland/Libraries/LibWeb/Painting/DisplayList.cpp @@ -76,19 +76,21 @@ void DisplayList::mark_unnecessary_commands() VERIFY(sample_blit_ranges.is_empty()); } -void DisplayList::execute(DisplayListPlayer& executor) +void DisplayListPlayer::execute(DisplayList& display_list) { + auto const& commands = display_list.commands(); + HashTable skipped_sample_corner_commands; size_t next_command_index = 0; - while (next_command_index < m_commands.size()) { - if (m_commands[next_command_index].skip) { + while (next_command_index < commands.size()) { + if (commands[next_command_index].skip) { next_command_index++; continue; } - auto& command = m_commands[next_command_index++].command; + auto& command = commands[next_command_index++].command; auto bounding_rect = command_bounding_rectangle(command); - if (bounding_rect.has_value() && (bounding_rect->is_empty() || executor.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))) { if (command.has()) { auto const& sample_under_corners = command.get(); skipped_sample_corner_commands.set(sample_under_corners.id); @@ -108,9 +110,9 @@ void DisplayList::execute(DisplayListPlayer& executor) } } -#define HANDLE_COMMAND(command_type, executor_method) \ - if (command.has()) { \ - executor.executor_method(command.get()); \ +#define HANDLE_COMMAND(command_type, executor_method) \ + if (command.has()) { \ + executor_method(command.get()); \ } // clang-format off diff --git a/Userland/Libraries/LibWeb/Painting/DisplayList.h b/Userland/Libraries/LibWeb/Painting/DisplayList.h index e7efe07c0da..7bdb281239d 100644 --- a/Userland/Libraries/LibWeb/Painting/DisplayList.h +++ b/Userland/Libraries/LibWeb/Painting/DisplayList.h @@ -32,10 +32,15 @@ namespace Web::Painting { +class DisplayList; + class DisplayListPlayer { public: virtual ~DisplayListPlayer() = default; + void execute(DisplayList& display_list); + +private: virtual void draw_glyph_run(DrawGlyphRun const&) = 0; virtual void fill_rect(FillRect const&) = 0; virtual void draw_scaled_bitmap(DrawScaledBitmap const&) = 0; @@ -74,15 +79,16 @@ public: void apply_scroll_offsets(Vector const& offsets_by_frame_id); void mark_unnecessary_commands(); - void execute(DisplayListPlayer&); -private: struct CommandListItem { Optional scroll_frame_id; Command command; bool skip { false }; }; + AK::SegmentedVector const& commands() const { return m_commands; } + +private: AK::SegmentedVector m_commands; }; diff --git a/Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h b/Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h index af0ca4aa4c7..1aab26847da 100644 --- a/Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h +++ b/Userland/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h @@ -33,6 +33,21 @@ public: class DisplayListPlayerSkia : public DisplayListPlayer { public: + DisplayListPlayerSkia(Gfx::Bitmap&); + +#ifdef USE_VULKAN + static OwnPtr create_vulkan_context(Core::VulkanContext&); + DisplayListPlayerSkia(SkiaBackendContext&, Gfx::Bitmap&); +#endif + +#ifdef AK_OS_MACOS + static OwnPtr create_metal_context(Core::MetalContext const&); + DisplayListPlayerSkia(SkiaBackendContext&, Core::MetalTexture&); +#endif + + virtual ~DisplayListPlayerSkia() override; + +private: void draw_glyph_run(DrawGlyphRun const&) override; void fill_rect(FillRect const&) override; void draw_scaled_bitmap(DrawScaledBitmap const&) override; @@ -65,21 +80,6 @@ public: bool would_be_fully_clipped_by_painter(Gfx::IntRect) const override; - DisplayListPlayerSkia(Gfx::Bitmap&); - -#ifdef USE_VULKAN - static OwnPtr create_vulkan_context(Core::VulkanContext&); - DisplayListPlayerSkia(SkiaBackendContext&, Gfx::Bitmap&); -#endif - -#ifdef AK_OS_MACOS - static OwnPtr create_metal_context(Core::MetalContext const&); - DisplayListPlayerSkia(SkiaBackendContext&, Core::MetalTexture&); -#endif - - virtual ~DisplayListPlayerSkia() override; - -private: class SkiaSurface; SkiaSurface& surface() const; diff --git a/Userland/Libraries/LibWeb/Painting/SVGMaskable.cpp b/Userland/Libraries/LibWeb/Painting/SVGMaskable.cpp index 5bd548b2750..b3fa199db60 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGMaskable.cpp +++ b/Userland/Libraries/LibWeb/Painting/SVGMaskable.cpp @@ -88,8 +88,8 @@ RefPtr SVGMaskable::calculate_mask_of_svg(PaintContext& context, CS paint_context.set_svg_transform(graphics_element.get_transform()); paint_context.set_draw_svg_geometry_for_clip_path(is(paintable)); StackingContext::paint_node_as_stacking_context(paintable, paint_context); - DisplayListPlayerSkia executor { *mask_bitmap }; - display_list.execute(executor); + DisplayListPlayerSkia display_list_player { *mask_bitmap }; + display_list_player.execute(display_list); return mask_bitmap; }; RefPtr mask_bitmap = {}; diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index 72fc7f1d2f1..24d588a8401 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -101,8 +101,8 @@ RefPtr SVGDecodedImageData::render(Gfx::IntSize size) const switch (painting_command_executor_type) { case DisplayListPlayerType::SkiaGPUIfAvailable: case DisplayListPlayerType::SkiaCPU: { - Painting::DisplayListPlayerSkia executor { *bitmap }; - display_list.execute(executor); + Painting::DisplayListPlayerSkia display_list_player { *bitmap }; + display_list_player.execute(display_list); break; } default: