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.
This commit is contained in:
parent
65962ba03d
commit
34a9f36e25
2 changed files with 76 additions and 0 deletions
|
|
@ -4,11 +4,16 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <LibGfx/ColorSpace.h>
|
||||
#include <LibGfx/DecodedImageFrame.h>
|
||||
#include <LibGfx/Filter.h>
|
||||
#include <LibGfx/FilterImpl.h>
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
|
|
@ -588,3 +593,63 @@ Filter deserialize_filter(ReadonlyBytes bytes, Function<Gfx::DecodedImageFrame(u
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
|
||||
static ErrorOr<void> 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<Gfx::DecodedImageFrame> decode_decoded_image_frame(Decoder& decoder)
|
||||
{
|
||||
auto bitmap = TRY(decoder.decode<Gfx::ShareableBitmap>());
|
||||
if (!bitmap.is_valid() || !bitmap.bitmap())
|
||||
return Error::from_string_literal("IPC decode: invalid filter image bitmap");
|
||||
auto color_space = TRY(decoder.decode<Gfx::ColorSpace>());
|
||||
return Gfx::DecodedImageFrame { *bitmap.bitmap(), move(color_space) };
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, Gfx::Filter const& filter)
|
||||
{
|
||||
HashMap<u64, Gfx::DecodedImageFrame> 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<Gfx::Filter> decode(Decoder& decoder)
|
||||
{
|
||||
auto filter_data = TRY(decoder.decode<ByteBuffer>());
|
||||
auto image_count = TRY(decoder.decode_size());
|
||||
HashMap<u64, Gfx::DecodedImageFrame> images;
|
||||
TRY(images.try_ensure_capacity(image_count));
|
||||
for (size_t i = 0; i < image_count; ++i) {
|
||||
auto id = TRY(decoder.decode<u64>());
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <LibGfx/Forward.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ScalingMode.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
|
|
@ -83,3 +84,13 @@ ByteBuffer serialize_filter(Filter const&, Function<u64(Gfx::DecodedImageFrame c
|
|||
Filter deserialize_filter(ReadonlyBytes, Function<Gfx::DecodedImageFrame(u64)> const& decode_image);
|
||||
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, Gfx::Filter const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<Gfx::Filter> decode(Decoder&);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue