From 34a9f36e253a2111c484f405d4288cf71654021a Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Wed, 20 May 2026 23:51:01 +0200 Subject: [PATCH] LibGfx: Add IPC serialization for Filter The compositor IPC path needs filters to carry their serialized value tree and any referenced image frames together. Keep that ownership in LibGfx by encoding the filter byte stream and each referenced frame as a shareable bitmap with its color space, then rebuilding the filter through the existing deserializer on decode. This is preparatory work required to add IPC between the main and compositor threads. --- Libraries/LibGfx/Filter.cpp | 65 +++++++++++++++++++++++++++++++++++++ Libraries/LibGfx/Filter.h | 11 +++++++ 2 files changed, 76 insertions(+) diff --git a/Libraries/LibGfx/Filter.cpp b/Libraries/LibGfx/Filter.cpp index 2fe754a230..f296a8d675 100644 --- a/Libraries/LibGfx/Filter.cpp +++ b/Libraries/LibGfx/Filter.cpp @@ -4,11 +4,16 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include #include #include #include +#include +#include +#include namespace Gfx { @@ -588,3 +593,63 @@ Filter deserialize_filter(ReadonlyBytes bytes, Function encode_decoded_image_frame(Encoder& encoder, u64 id, Gfx::DecodedImageFrame const& frame) +{ + auto bitmap = frame.bitmap().to_shareable_bitmap(); + if (!bitmap.is_valid()) + return Error::from_string_literal("IPC encode: failed to create shareable bitmap for filter image"); + TRY(encoder.encode(id)); + TRY(encoder.encode(bitmap)); + TRY(encoder.encode(frame.color_space())); + return {}; +} + +static ErrorOr decode_decoded_image_frame(Decoder& decoder) +{ + auto bitmap = TRY(decoder.decode()); + if (!bitmap.is_valid() || !bitmap.bitmap()) + return Error::from_string_literal("IPC decode: invalid filter image bitmap"); + auto color_space = TRY(decoder.decode()); + return Gfx::DecodedImageFrame { *bitmap.bitmap(), move(color_space) }; +} + +template<> +ErrorOr encode(Encoder& encoder, Gfx::Filter const& filter) +{ + HashMap images; + auto filter_data = Gfx::serialize_filter(filter, [&](Gfx::DecodedImageFrame const& frame) { + images.ensure(frame.id(), [&] { return frame; }); + return frame.id(); + }); + + TRY(encoder.encode(filter_data)); + TRY(encoder.encode_size(images.size())); + for (auto const& image : images) + TRY(encode_decoded_image_frame(encoder, image.key, image.value)); + return {}; +} + +template<> +ErrorOr decode(Decoder& decoder) +{ + auto filter_data = TRY(decoder.decode()); + auto image_count = TRY(decoder.decode_size()); + HashMap images; + TRY(images.try_ensure_capacity(image_count)); + for (size_t i = 0; i < image_count; ++i) { + auto id = TRY(decoder.decode()); + auto frame = TRY(decode_decoded_image_frame(decoder)); + TRY(images.try_set(id, move(frame))); + } + + return Gfx::deserialize_filter(filter_data.bytes(), [&](u64 image_id) { + auto image = images.get(image_id); + VERIFY(image.has_value()); + return image.value(); + }); +} + +} diff --git a/Libraries/LibGfx/Filter.h b/Libraries/LibGfx/Filter.h index eb94a049a1..5c5880b868 100644 --- a/Libraries/LibGfx/Filter.h +++ b/Libraries/LibGfx/Filter.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace Gfx { @@ -83,3 +84,13 @@ ByteBuffer serialize_filter(Filter const&, Function const& decode_image); } + +namespace IPC { + +template<> +ErrorOr encode(Encoder&, Gfx::Filter const&); + +template<> +ErrorOr decode(Decoder&); + +}