mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
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.
This commit is contained in:
parent
5a796629c6
commit
e8b7c88881
Notes:
github-actions[bot]
2024-07-25 12:34:47 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/e8b7c88881c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/826
6 changed files with 41 additions and 33 deletions
|
@ -1209,7 +1209,7 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting::
|
|||
auto& iosurface_backing_store = static_cast<Painting::IOSurfaceBackingStore&>(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:
|
||||
|
|
|
@ -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<u32> 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<SampleUnderCorners>()) {
|
||||
auto const& sample_under_corners = command.get<SampleUnderCorners>();
|
||||
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<command_type>()) { \
|
||||
executor.executor_method(command.get<command_type>()); \
|
||||
#define HANDLE_COMMAND(command_type, executor_method) \
|
||||
if (command.has<command_type>()) { \
|
||||
executor_method(command.get<command_type>()); \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
|
|
@ -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<Gfx::IntPoint> const& offsets_by_frame_id);
|
||||
void mark_unnecessary_commands();
|
||||
void execute(DisplayListPlayer&);
|
||||
|
||||
private:
|
||||
struct CommandListItem {
|
||||
Optional<i32> scroll_frame_id;
|
||||
Command command;
|
||||
bool skip { false };
|
||||
};
|
||||
|
||||
AK::SegmentedVector<CommandListItem, 512> const& commands() const { return m_commands; }
|
||||
|
||||
private:
|
||||
AK::SegmentedVector<CommandListItem, 512> m_commands;
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,21 @@ public:
|
|||
|
||||
class DisplayListPlayerSkia : public DisplayListPlayer {
|
||||
public:
|
||||
DisplayListPlayerSkia(Gfx::Bitmap&);
|
||||
|
||||
#ifdef USE_VULKAN
|
||||
static OwnPtr<SkiaBackendContext> create_vulkan_context(Core::VulkanContext&);
|
||||
DisplayListPlayerSkia(SkiaBackendContext&, Gfx::Bitmap&);
|
||||
#endif
|
||||
|
||||
#ifdef AK_OS_MACOS
|
||||
static OwnPtr<SkiaBackendContext> 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<SkiaBackendContext> create_vulkan_context(Core::VulkanContext&);
|
||||
DisplayListPlayerSkia(SkiaBackendContext&, Gfx::Bitmap&);
|
||||
#endif
|
||||
|
||||
#ifdef AK_OS_MACOS
|
||||
static OwnPtr<SkiaBackendContext> create_metal_context(Core::MetalContext const&);
|
||||
DisplayListPlayerSkia(SkiaBackendContext&, Core::MetalTexture&);
|
||||
#endif
|
||||
|
||||
virtual ~DisplayListPlayerSkia() override;
|
||||
|
||||
private:
|
||||
class SkiaSurface;
|
||||
SkiaSurface& surface() const;
|
||||
|
||||
|
|
|
@ -88,8 +88,8 @@ RefPtr<Gfx::Bitmap> 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<SVGClipPaintable>(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<Gfx::Bitmap> mask_bitmap = {};
|
||||
|
|
|
@ -101,8 +101,8 @@ RefPtr<Gfx::Bitmap> 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:
|
||||
|
|
Loading…
Reference in a new issue