1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:24:57 +00:00

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.
This commit is contained in:
Andreas Kling 2021-02-20 11:35:00 +01:00
parent 8fb9d1fd1d
commit 3b9f110161
3 changed files with 26 additions and 3 deletions

View file

@ -35,6 +35,12 @@ Client::Client()
handshake();
}
void Client::die()
{
if (on_death)
on_death();
}
void Client::handshake()
{
send_sync<Messages::ImageDecoderServer::Greet>();

View file

@ -44,7 +44,7 @@ struct DecodedImage {
Vector<Frame> frames;
};
class Client
class Client final
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
, public ImageDecoderClientEndpoint {
C_OBJECT(Client);
@ -54,9 +54,13 @@ public:
Optional<DecodedImage> decode_image(const ByteBuffer&);
Function<void()> on_death;
private:
Client();
virtual void die() override;
virtual void handle(const Messages::ImageDecoderClient::Dummy&) override;
};

View file

@ -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<ImageDecoderClient::Client> 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;