ladybird/Libraries/LibWeb/Painting/DisplayListResourceStorage.cpp
Aliaksandr Kalenik 3c9df3fccd LibWeb: Inline serialized filters in display list commands
Prep work for serializing display lists across the IPC boundary. Replace
Gfx::Filter's Skia-specific backing with a portable Variant-based
representation, add serialize_filter/deserialize_filter, and store
filter data inline in ApplyEffects/ApplyBackdropFilter command payloads
instead of in DisplayListResourceStorage. FilterResourceId is removed
along with the per-storage filter map.
2026-05-11 15:49:12 +02:00

111 lines
4.1 KiB
C++

/*
* Copyright (c) 2026, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/Filter.h>
#include <LibGfx/Font/Font.h>
#include <LibWeb/Painting/DisplayList.h>
#include <LibWeb/Painting/DisplayListResourceStorage.h>
namespace Web::Painting {
DisplayListResourceStorage::~DisplayListResourceStorage() = default;
FontResourceId DisplayListResourceStorage::add_font(Gfx::Font const& font)
{
auto id = font.id();
m_fonts.ensure(id, [&]() -> NonnullRefPtr<Gfx::Font const> {
return font;
});
return { id };
}
ImageFrameResourceId DisplayListResourceStorage::add_image_frame(Gfx::DecodedImageFrame const& frame)
{
auto id = frame.id();
m_image_frames.ensure(id, [&] {
return frame;
});
return { id };
}
ExternalContentResourceId DisplayListResourceStorage::add_external_content_source(
NonnullRefPtr<ExternalContentSource const> source)
{
auto id = source->id();
m_external_content_sources.ensure(id, [&] {
return move(source);
});
return { id };
}
VideoFrameResourceId DisplayListResourceStorage::add_video_frame_source(NonnullRefPtr<VideoFrameSource const> source)
{
auto id = source->id();
m_video_frame_sources.ensure(id, [&] {
return move(source);
});
return { id };
}
DisplayListResourceId DisplayListResourceStorage::add_display_list(NonnullRefPtr<DisplayList const> display_list)
{
auto id = display_list->id();
m_display_lists.ensure(id, [&] {
return move(display_list);
});
return { id };
}
static ReadonlyBytes inline_data(ReadonlyBytes payload, DisplayListDataSpan span)
{
VERIFY(static_cast<size_t>(span.offset) + span.size <= payload.size());
return payload.slice(span.offset, span.size);
}
void DisplayListResourceStorage::append_referenced_resources_from(
DisplayListResourceStorage const& source,
ReadonlyBytes command_bytes)
{
DisplayList::for_each_command_header(command_bytes, [&](DisplayListCommandHeader const& header, ReadonlyBytes payload) {
visit_display_list_command(header.type, payload, [&](auto const& command) {
if constexpr (requires { command.font_id; })
add_font(source.font(command.font_id));
if constexpr (requires { command.frame_id; })
add_image_frame(source.image_frame(command.frame_id));
if constexpr (requires { source.external_content_source(command.source_id); })
add_external_content_source(source.external_content_source(command.source_id));
if constexpr (requires { source.video_frame_source(command.source_id); })
add_video_frame_source(source.video_frame_source(command.source_id));
if constexpr (requires { command.paint_style; command.paint_kind; }) {
if (command.paint_kind == decltype(command.paint_kind)::PaintStyle
&& command.paint_style.type == DisplayListPaintStyleType::Pattern)
add_display_list(source.display_list(command.paint_style.pattern_tile_display_list_id));
}
if constexpr (requires { command.backdrop_filter_data; }) {
if (command.has_backdrop_filter) {
Gfx::deserialize_filter(inline_data(payload, command.backdrop_filter_data), [&](u64 image_id) {
auto const& frame = source.image_frame(ImageFrameResourceId { image_id });
add_image_frame(frame);
return frame;
});
}
}
if constexpr (requires { command.filter_data; }) {
if (command.has_filter) {
Gfx::deserialize_filter(inline_data(payload, command.filter_data), [&](u64 image_id) {
auto const& frame = source.image_frame(ImageFrameResourceId { image_id });
add_image_frame(frame);
return frame;
});
}
}
if constexpr (requires { command.display_list_id; })
add_display_list(source.display_list(command.display_list_id));
});
});
}
}