LibGfx: Preserve single-frame BitmapSequence backing

BitmapSequence IPC decodes every frame from the collated transport
buffer into a new malloc-backed Bitmap. That keeps animated sequences
compact, but it also breaks the shared-memory chain for the common
single-frame image path. WebContent receives anonymous buffer data from
ImageDecoder, then has to allocate another anonymous buffer when the
image is sent to the Compositor.

Preserve the backing for single-frame sequences by wrapping the received
AnonymousBuffer directly in the decoded Bitmap after validating that it
exactly matches the frame metadata. That lets the decoded image keep its
shared-memory backing all the way through ImageDecoder -> WebContent ->
Compositor without another allocation and copy.
This commit is contained in:
Aliaksandr Kalenik 2026-05-25 18:32:21 +02:00 committed by Alexander Kalenik
parent 5a740161b3
commit 411e74d51c

View file

@ -114,6 +114,17 @@ ErrorOr<Gfx::BitmapSequence> decode(Decoder& decoder)
auto& bitmaps = result.bitmaps;
TRY(bitmaps.try_ensure_capacity(metadata_list.size()));
// Single-frame sequences can keep the transferred backing directly.
if (metadata_list.size() == 1 && metadata_list[0].has_value()) {
auto metadata = metadata_list[0].value();
if (!collated_buffer.is_valid() || metadata.size_in_bytes != total_buffer_size || metadata.size_in_bytes != collated_buffer.size())
return Error::from_string_literal("IPC: Invalid Gfx::BitmapSequence buffer data");
RefPtr<Gfx::Bitmap> bitmap = TRY(Gfx::Bitmap::create_with_anonymous_buffer(metadata.format, metadata.alpha_type, move(collated_buffer), metadata.size));
bitmaps.unchecked_append(move(bitmap));
return result;
}
ReadonlyBytes bytes = ReadonlyBytes(collated_buffer.data<u8>(), collated_buffer.size());
size_t bytes_read = 0;