This abstraction will help us to support multiple IPC transport
mechanisms going forward. For now, we only have a TransportSocket that
implements the same behavior we previously had, using Unix Sockets for
IPC.
There is an issue where gifs with many frames cannot be loaded, as each
bitmap is sent over IPC using a separate file descriptor, and there is
limit on the maximum number of descriptors per IPC message. Thus, trying
to load gifs with more than 64 frames (the current limit) causes the
image decoder process to die.
This commit introduces the BitmapSequence class, which is a thin wrapper
around the type Vector<Optional<NonnullRefPtr<Gfx::Bitmap>>> and
provides an IPC encode/decode routine that collates all bitmap data into
a single buffer so that only a single file descriptor is required per
IPC transfer, even if multiple frames are being sent.
Before this change, we were passing them as Gfx::ShareableBitmap. The
problem is that shareable bitmaps keep their underlying file descriptor
open, so that they can be shared again with someone else.
When a Gfx::Bitmap is decoded from an IPC message, the file descriptor
is closed and recovered immediately.
This fixes an issue where we'd accumulate one file descriptor for every
image decoded. This eventually led to descriptor starvation after enough
images were loaded and still referenced at the same time.
This is the same behavior as RequestServer, with the added benefit that
we know how to gracefully reconnect ImageDecoder to all WebContent
processes on restart.
ImageDecoder now queues up image decoding requests and returns the
images back to the caller later. ImageDecoderClient has a new
promise-based API that allows callers to attach their own resolve/reject
handlers to the responses from ImageDecoder.
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
$ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
Meta Ports Ladybird Tests Kernel)
$ perl -pie 's/\bDeprecatedString\b/ByteString/g;
s/deprecated_string/byte_string/g' $xs
$ clang-format --style=file -i \
$(git diff --name-only | grep \.cpp\|\.h)
$ gn format $(git ls-files '*.gn' '*.gni')
Originally I simply thought that passing file paths is quite OK, but as
Linus pointed to, it turned out that passing file paths to ensure some
files are able to be decoded is awkward because it does not work with
images being served over HTTP.
Therefore, ideally we should just use the MIME type as an optional
argument to ensure that we can always fallback to use that in case
sniffing for the correct image type has failed so we can still detect
files like with the TGA format, which has no magic bytes.
Because TGA images don't have magic bytes as a signature to be detected,
instead assume a sequence of ReadonlyBytes is a possible TGA image only
if we are given a path so we could check the extension of the file and
see if it's a TGA image.
When we know the path of the file being loaded, we will try to first
check its extension, and only if there's no match to a known decoder,
based on simple extension lookup, then we would probe for other formats
as usual with the normal sniffing method.