ladybird/Userland/Libraries/LibImageDecoderClient/Client.h
Andreas Kling 166e603c5e ImageDecoder: Pass decoded images as Gfx::Bitmap over IPC
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.
2024-07-18 09:05:10 +02:00

51 lines
1.5 KiB
C++

/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/HashMap.h>
#include <ImageDecoder/ImageDecoderClientEndpoint.h>
#include <ImageDecoder/ImageDecoderServerEndpoint.h>
#include <LibCore/Promise.h>
#include <LibIPC/ConnectionToServer.h>
namespace ImageDecoderClient {
struct Frame {
NonnullRefPtr<Gfx::Bitmap> bitmap;
u32 duration { 0 };
};
struct DecodedImage {
bool is_animated { false };
Gfx::FloatPoint scale { 1, 1 };
u32 loop_count { 0 };
Vector<Frame> frames;
};
class Client final
: public IPC::ConnectionToServer<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
, public ImageDecoderClientEndpoint {
IPC_CLIENT_CONNECTION(Client, "/tmp/session/%sid/portal/image"sv);
public:
Client(NonnullOwnPtr<Core::LocalSocket>);
NonnullRefPtr<Core::Promise<DecodedImage>> decode_image(ReadonlyBytes, Function<ErrorOr<void>(DecodedImage&)> on_resolved, Function<void(Error&)> on_rejected, Optional<Gfx::IntSize> ideal_size = {}, Optional<ByteString> mime_type = {});
Function<void()> on_death;
private:
virtual void die() override;
virtual void did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Vector<Optional<NonnullRefPtr<Gfx::Bitmap>>> const& bitmaps, Vector<u32> const& durations, Gfx::FloatPoint scale) override;
virtual void did_fail_to_decode_image(i64 image_id, String const& error_message) override;
HashMap<i64, NonnullRefPtr<Core::Promise<DecodedImage>>> m_pending_decoded_images;
};
}