diff --git a/Libraries/LibImageDecoderClient/Client.cpp b/Libraries/LibImageDecoderClient/Client.cpp index 2cb3774a895..8e4f9807ff9 100644 --- a/Libraries/LibImageDecoderClient/Client.cpp +++ b/Libraries/LibImageDecoderClient/Client.cpp @@ -17,10 +17,10 @@ Client::Client(NonnullOwnPtr transport) void Client::die() { verify_event_loop(); - for (auto& [_, promise] : m_pending_decoded_images) { - promise->reject(Error::from_string_literal("ImageDecoder disconnected")); - } - m_pending_decoded_images.clear(); + auto pending_promises = move(m_token_promises); + + for (auto& promise : pending_promises) + promise.value->reject(Error::from_string_literal("ImageDecoder disconnected")); } NonnullRefPtr> Client::decode_image(ReadonlyBytes encoded_data, Function(DecodedImage&)> on_resolved, Function on_rejected, Optional ideal_size, Optional mime_type) @@ -47,27 +47,24 @@ NonnullRefPtr> Client::decode_image(ReadonlyBytes en memcpy(encoded_buffer.data(), encoded_data.data(), encoded_data.size()); - auto response = send_sync_but_allow_failure(move(encoded_buffer), ideal_size, mime_type); - if (!response) { - dbgln("ImageDecoder disconnected trying to decode image"); - promise->reject(Error::from_string_literal("ImageDecoder disconnected")); - return promise; - } + i64 request_id = m_next_request_id++; + m_token_promises.set(request_id, promise); - m_pending_decoded_images.set(response->image_id(), promise); + async_decode_image(encoded_buffer, ideal_size, mime_type, request_id); return promise; } -void Client::did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmap_sequence, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_space, i64 session_id) +void Client::did_decode_image(i64 request_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmap_sequence, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_space, i64 session_id) { verify_event_loop(); auto bitmaps = move(bitmap_sequence.bitmaps); VERIFY(!bitmaps.is_empty()); - auto maybe_promise = m_pending_decoded_images.take(image_id); + Optional>> maybe_promise = m_token_promises.take(request_id); + if (!maybe_promise.has_value()) { - dbgln("ImageDecoderClient: No pending image with ID {}", image_id); + dbgln("ImageDecoderClient: No pending image with request token {}", request_id); return; } auto promise = maybe_promise.release_value(); @@ -89,7 +86,7 @@ void Client::did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Gf for (size_t i = 0; i < bitmaps.size(); ++i) { if (!bitmaps[i]) { - dbgln("ImageDecoderClient: Invalid bitmap for request {} at index {}", image_id, i); + dbgln("ImageDecoderClient: Invalid bitmap for request {} at index {}", request_id, i); promise->reject(Error::from_string_literal("Invalid bitmap")); return; } @@ -101,17 +98,18 @@ void Client::did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Gf promise->resolve(move(image)); } -void Client::did_fail_to_decode_image(i64 image_id, String error_message) +void Client::did_fail_to_decode_image(i64 request_id, String error_message) { verify_event_loop(); - auto maybe_promise = m_pending_decoded_images.take(image_id); + Optional>> maybe_promise = m_token_promises.take(request_id); + if (!maybe_promise.has_value()) { - dbgln("ImageDecoderClient: No pending image with ID {}", image_id); + dbgln("ImageDecoderClient: No pending image with request token {}", request_id); return; } auto promise = maybe_promise.release_value(); - dbgln("ImageDecoderClient: Failed to decode image with ID {}: {}", image_id, error_message); + dbgln("ImageDecoderClient: Failed to decode image with request token {}: {}", request_id, error_message); // FIXME: Include the error message in the Error object when Errors are allowed to hold Strings promise->reject(Error::from_string_literal("Image decoding failed or aborted")); } diff --git a/Libraries/LibImageDecoderClient/Client.h b/Libraries/LibImageDecoderClient/Client.h index bab18f1433b..5bef5d4e4c1 100644 --- a/Libraries/LibImageDecoderClient/Client.h +++ b/Libraries/LibImageDecoderClient/Client.h @@ -55,14 +55,15 @@ private: void verify_event_loop() const; virtual void die() override; - virtual void did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmap_sequence, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_space, i64 session_id) override; - virtual void did_fail_to_decode_image(i64 image_id, String error_message) override; + virtual void did_decode_image(i64 request_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmap_sequence, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_space, i64 session_id) override; + virtual void did_fail_to_decode_image(i64 request_id, String error_message) override; virtual void did_decode_animation_frames(i64 session_id, Gfx::BitmapSequence bitmaps) override; virtual void did_fail_animation_decode(i64 session_id, String error_message) override; Core::EventLoop* m_creation_event_loop { &Core::EventLoop::current() }; - HashMap>> m_pending_decoded_images; + i64 m_next_request_id { 0 }; + HashMap>> m_token_promises; }; } diff --git a/Services/ImageDecoder/ConnectionFromClient.cpp b/Services/ImageDecoder/ConnectionFromClient.cpp index e5272ff6106..266c6f1c197 100644 --- a/Services/ImageDecoder/ConnectionFromClient.cpp +++ b/Services/ImageDecoder/ConnectionFromClient.cpp @@ -183,13 +183,13 @@ static ErrorOr decode_image_to_details(Core: return result; } -NonnullRefPtr ConnectionFromClient::make_decode_image_job(i64 image_id, Core::AnonymousBuffer encoded_buffer, Optional ideal_size, Optional mime_type) +NonnullRefPtr ConnectionFromClient::make_decode_image_job(i64 request_id, Core::AnonymousBuffer encoded_buffer, Optional ideal_size, Optional mime_type) { return Job::construct( [encoded_buffer = move(encoded_buffer), ideal_size = move(ideal_size), mime_type = move(mime_type)](auto&) mutable -> ErrorOr { return TRY(decode_image_to_details(move(encoded_buffer), ideal_size, mime_type)); }, - [strong_this = NonnullRefPtr(*this), image_id](DecodeResult result) -> ErrorOr { + [strong_this = NonnullRefPtr(*this), request_id](DecodeResult result) -> ErrorOr { i64 session_id = 0; if (result.decoder) { @@ -202,35 +202,31 @@ NonnullRefPtr ConnectionFromClient::make_decode_image strong_this->m_animation_sessions.set(session_id, move(session)); } - strong_this->async_did_decode_image(image_id, result.is_animated, result.loop_count, move(result.bitmaps), move(result.durations), result.scale, move(result.color_profile), session_id); - strong_this->m_pending_jobs.remove(image_id); + strong_this->async_did_decode_image(request_id, result.is_animated, result.loop_count, move(result.bitmaps), move(result.durations), result.scale, move(result.color_profile), session_id); + strong_this->m_pending_jobs.remove(request_id); return {}; }, - [strong_this = NonnullRefPtr(*this), image_id](Error error) -> void { + [strong_this = NonnullRefPtr(*this), request_id](Error error) -> void { if (strong_this->is_open()) - strong_this->async_did_fail_to_decode_image(image_id, MUST(String::formatted("Decoding failed: {}", error))); - strong_this->m_pending_jobs.remove(image_id); + strong_this->async_did_fail_to_decode_image(request_id, MUST(String::formatted("Decoding failed: {}", error))); + strong_this->m_pending_jobs.remove(request_id); }); } -Messages::ImageDecoderServer::DecodeImageResponse ConnectionFromClient::decode_image(Core::AnonymousBuffer encoded_buffer, Optional ideal_size, Optional mime_type) +void ConnectionFromClient::decode_image(Core::AnonymousBuffer encoded_buffer, Optional ideal_size, Optional mime_type, i64 request_id) { - auto image_id = m_next_image_id++; - if (!encoded_buffer.is_valid()) { dbgln_if(IMAGE_DECODER_DEBUG, "Encoded data is invalid"); - async_did_fail_to_decode_image(image_id, "Encoded data is invalid"_string); - return image_id; + async_did_fail_to_decode_image(request_id, "Encoded data is invalid"_string); + return; } - m_pending_jobs.set(image_id, make_decode_image_job(image_id, move(encoded_buffer), ideal_size, move(mime_type))); - - return image_id; + m_pending_jobs.set(request_id, make_decode_image_job(request_id, move(encoded_buffer), ideal_size, move(mime_type))); } -void ConnectionFromClient::cancel_decoding(i64 image_id) +void ConnectionFromClient::cancel_decoding(i64 request_id) { - if (auto job = m_pending_jobs.take(image_id); job.has_value()) { + if (auto job = m_pending_jobs.take(request_id); job.has_value()) { job.value()->cancel(); } } diff --git a/Services/ImageDecoder/ConnectionFromClient.h b/Services/ImageDecoder/ConnectionFromClient.h index c1fc9f88b8c..a2f34b4249a 100644 --- a/Services/ImageDecoder/ConnectionFromClient.h +++ b/Services/ImageDecoder/ConnectionFromClient.h @@ -55,8 +55,8 @@ private: explicit ConnectionFromClient(NonnullOwnPtr); - virtual Messages::ImageDecoderServer::DecodeImageResponse decode_image(Core::AnonymousBuffer, Optional ideal_size, Optional mime_type) override; - virtual void cancel_decoding(i64 image_id) override; + virtual void decode_image(Core::AnonymousBuffer, Optional ideal_size, Optional mime_type, i64 request_id) override; + virtual void cancel_decoding(i64 request_id) override; virtual void request_animation_frames(i64 session_id, u32 start_frame_index, u32 count) override; virtual void stop_animation_decode(i64 session_id) override; virtual Messages::ImageDecoderServer::ConnectNewClientsResponse connect_new_clients(size_t count) override; @@ -64,9 +64,8 @@ private: ErrorOr connect_new_client(); - NonnullRefPtr make_decode_image_job(i64 image_id, Core::AnonymousBuffer, Optional ideal_size, Optional mime_type); + NonnullRefPtr make_decode_image_job(i64 request_id, Core::AnonymousBuffer, Optional ideal_size, Optional mime_type); - i64 m_next_image_id { 0 }; i64 m_next_session_id { 1 }; HashMap> m_pending_jobs; HashMap> m_animation_sessions; diff --git a/Services/ImageDecoder/ImageDecoderClient.ipc b/Services/ImageDecoder/ImageDecoderClient.ipc index d45052998cf..4e1fe278256 100644 --- a/Services/ImageDecoder/ImageDecoderClient.ipc +++ b/Services/ImageDecoder/ImageDecoderClient.ipc @@ -3,8 +3,8 @@ endpoint ImageDecoderClient { - did_decode_image(i64 image_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmaps, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_profile, i64 session_id) =| - did_fail_to_decode_image(i64 image_id, String error_message) =| + did_decode_image(i64 request_id, bool is_animated, u32 loop_count, Gfx::BitmapSequence bitmaps, Vector durations, Gfx::FloatPoint scale, Gfx::ColorSpace color_profile, i64 session_id) =| + did_fail_to_decode_image(i64 request_id, String error_message) =| did_decode_animation_frames(i64 session_id, Gfx::BitmapSequence bitmaps) =| did_fail_animation_decode(i64 session_id, String error_message) =| diff --git a/Services/ImageDecoder/ImageDecoderServer.ipc b/Services/ImageDecoder/ImageDecoderServer.ipc index 22078faadad..21b5e671352 100644 --- a/Services/ImageDecoder/ImageDecoderServer.ipc +++ b/Services/ImageDecoder/ImageDecoderServer.ipc @@ -3,8 +3,8 @@ endpoint ImageDecoderServer { init_transport(int peer_pid) => (int peer_pid) - decode_image(Core::AnonymousBuffer data, Optional ideal_size, Optional mime_type) => (i64 image_id) - cancel_decoding(i64 image_id) =| + decode_image(Core::AnonymousBuffer data, Optional ideal_size, Optional mime_type, i64 request_id) =| + cancel_decoding(i64 request_id) =| request_animation_frames(i64 session_id, u32 start_frame_index, u32 count) =| stop_animation_decode(i64 session_id) =|