From 3b9f110161bc78d8534a29e3f14030e1f5a15574 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 20 Feb 2021 11:35:00 +0100 Subject: [PATCH] LibWeb+LibImageDecoderClient: Reuse ImageDecoder service process The overhead from spawning a new ImageDecoder for every decoding job is way too large and causing other problems as well (#5421) Let's keep the same decoder open and reuse it as long as it's working. --- .../Libraries/LibImageDecoderClient/Client.cpp | 6 ++++++ .../Libraries/LibImageDecoderClient/Client.h | 6 +++++- .../Libraries/LibWeb/Loader/ImageResource.cpp | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibImageDecoderClient/Client.cpp b/Userland/Libraries/LibImageDecoderClient/Client.cpp index 5ac14c63b1d..f8428f060ae 100644 --- a/Userland/Libraries/LibImageDecoderClient/Client.cpp +++ b/Userland/Libraries/LibImageDecoderClient/Client.cpp @@ -35,6 +35,12 @@ Client::Client() handshake(); } +void Client::die() +{ + if (on_death) + on_death(); +} + void Client::handshake() { send_sync(); diff --git a/Userland/Libraries/LibImageDecoderClient/Client.h b/Userland/Libraries/LibImageDecoderClient/Client.h index 11d0b775455..ba6664fcacc 100644 --- a/Userland/Libraries/LibImageDecoderClient/Client.h +++ b/Userland/Libraries/LibImageDecoderClient/Client.h @@ -44,7 +44,7 @@ struct DecodedImage { Vector frames; }; -class Client +class Client final : public IPC::ServerConnection , public ImageDecoderClientEndpoint { C_OBJECT(Client); @@ -54,9 +54,13 @@ public: Optional decode_image(const ByteBuffer&); + Function on_death; + private: Client(); + virtual void die() override; + virtual void handle(const Messages::ImageDecoderClient::Dummy&) override; }; diff --git a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp index ba94e8d039f..001eb308776 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp @@ -48,6 +48,18 @@ int ImageResource::frame_duration(size_t frame_index) const return m_decoded_frames[frame_index].duration; } +static ImageDecoderClient::Client& image_decoder_client() +{ + static RefPtr image_decoder_client; + if (!image_decoder_client) { + image_decoder_client = ImageDecoderClient::Client::construct(); + image_decoder_client->on_death = [&] { + image_decoder_client = nullptr; + }; + } + return *image_decoder_client; +} + void ImageResource::decode_if_needed() const { if (!has_encoded_data()) @@ -59,8 +71,9 @@ void ImageResource::decode_if_needed() const if (!m_decoded_frames.is_empty()) return; - auto image_decoder_client = ImageDecoderClient::Client::construct(); - auto image = image_decoder_client->decode_image(encoded_data()); + NonnullRefPtr decoder = image_decoder_client(); + auto image = decoder->decode_image(encoded_data()); + if (image.has_value()) { m_loop_count = image.value().loop_count; m_animated = image.value().is_animated;