mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 09:58:11 +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:
parent
8fb9d1fd1d
commit
3b9f110161
3 changed files with 26 additions and 3 deletions
|
@ -35,6 +35,12 @@ Client::Client()
|
||||||
handshake();
|
handshake();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::die()
|
||||||
|
{
|
||||||
|
if (on_death)
|
||||||
|
on_death();
|
||||||
|
}
|
||||||
|
|
||||||
void Client::handshake()
|
void Client::handshake()
|
||||||
{
|
{
|
||||||
send_sync<Messages::ImageDecoderServer::Greet>();
|
send_sync<Messages::ImageDecoderServer::Greet>();
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct DecodedImage {
|
||||||
Vector<Frame> frames;
|
Vector<Frame> frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Client
|
class Client final
|
||||||
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
||||||
, public ImageDecoderClientEndpoint {
|
, public ImageDecoderClientEndpoint {
|
||||||
C_OBJECT(Client);
|
C_OBJECT(Client);
|
||||||
|
@ -54,9 +54,13 @@ public:
|
||||||
|
|
||||||
Optional<DecodedImage> decode_image(const ByteBuffer&);
|
Optional<DecodedImage> decode_image(const ByteBuffer&);
|
||||||
|
|
||||||
|
Function<void()> on_death;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Client();
|
Client();
|
||||||
|
|
||||||
|
virtual void die() override;
|
||||||
|
|
||||||
virtual void handle(const Messages::ImageDecoderClient::Dummy&) override;
|
virtual void handle(const Messages::ImageDecoderClient::Dummy&) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,18 @@ int ImageResource::frame_duration(size_t frame_index) const
|
||||||
return m_decoded_frames[frame_index].duration;
|
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
|
void ImageResource::decode_if_needed() const
|
||||||
{
|
{
|
||||||
if (!has_encoded_data())
|
if (!has_encoded_data())
|
||||||
|
@ -59,8 +71,9 @@ void ImageResource::decode_if_needed() const
|
||||||
if (!m_decoded_frames.is_empty())
|
if (!m_decoded_frames.is_empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto image_decoder_client = ImageDecoderClient::Client::construct();
|
NonnullRefPtr decoder = image_decoder_client();
|
||||||
auto image = image_decoder_client->decode_image(encoded_data());
|
auto image = decoder->decode_image(encoded_data());
|
||||||
|
|
||||||
if (image.has_value()) {
|
if (image.has_value()) {
|
||||||
m_loop_count = image.value().loop_count;
|
m_loop_count = image.value().loop_count;
|
||||||
m_animated = image.value().is_animated;
|
m_animated = image.value().is_animated;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue