@@ -56,21 +56,68 @@ sk_sp<SkImage> ConvertBufferToSkImage(
5656 return raster_image;
5757}
5858
59- void DoConvertImageToRasterImpeller (
59+ [[nodiscard]] fml::Status DoConvertImageToRasterImpeller (
6060 const sk_sp<DlImage>& dl_image,
61- std::function<void (fml::StatusOr<sk_sp<SkImage>>)> encode_task,
61+ const std::function<void (fml::StatusOr<sk_sp<SkImage>>)>& encode_task,
6262 const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
6363 const std::shared_ptr<impeller::Context>& impeller_context) {
64+ fml::Status result;
6465 is_gpu_disabled_sync_switch->Execute (
6566 fml::SyncSwitch::Handlers ()
66- .SetIfTrue ([&encode_task ] {
67- encode_task (
68- fml::Status (fml::StatusCode::kUnavailable , " GPU unavailable." )) ;
67+ .SetIfTrue ([&result ] {
68+ result =
69+ fml::Status (fml::StatusCode::kUnavailable , " GPU unavailable." );
6970 })
7071 .SetIfFalse ([&dl_image, &encode_task, &impeller_context] {
7172 ImageEncodingImpeller::ConvertDlImageToSkImage (
72- dl_image, std::move ( encode_task) , impeller_context);
73+ dl_image, encode_task, impeller_context);
7374 }));
75+ return result;
76+ }
77+
78+ // / Same as `DoConvertImageToRasterImpeller` but it will attempt to retry the
79+ // / operation if `DoConvertImageToRasterImpeller` returns kUnavailable when the
80+ // / GPU becomes available again.
81+ void DoConvertImageToRasterImpellerWithRetry (
82+ const sk_sp<DlImage>& dl_image,
83+ std::function<void (fml::StatusOr<sk_sp<SkImage>>)>&& encode_task,
84+ const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
85+ const std::shared_ptr<impeller::Context>& impeller_context,
86+ const fml::RefPtr<fml::TaskRunner>& retry_runner) {
87+ fml::Status status = DoConvertImageToRasterImpeller (
88+ dl_image, encode_task, is_gpu_disabled_sync_switch, impeller_context);
89+ if (!status.ok ()) {
90+ // If the conversion failed because of the GPU is unavailable, store the
91+ // task on the Context so it can be executed when the GPU becomes available.
92+ if (status.code () == fml::StatusCode::kUnavailable ) {
93+ impeller_context->StoreTaskForGPU (
94+ [dl_image, encode_task = std::move (encode_task),
95+ is_gpu_disabled_sync_switch, impeller_context,
96+ retry_runner]() mutable {
97+ auto retry_task = [dl_image, encode_task = std::move (encode_task),
98+ is_gpu_disabled_sync_switch, impeller_context] {
99+ fml::Status retry_status = DoConvertImageToRasterImpeller (
100+ dl_image, encode_task, is_gpu_disabled_sync_switch,
101+ impeller_context);
102+ if (!retry_status.ok ()) {
103+ // The retry failed for some reason, maybe the GPU became
104+ // unavailable again. Don't retry again, just fail in this case.
105+ encode_task (retry_status);
106+ }
107+ };
108+ // If a `retry_runner` is specified, post the retry to it, otherwise
109+ // execute it directly.
110+ if (retry_runner) {
111+ retry_runner->PostTask (retry_task);
112+ } else {
113+ retry_task ();
114+ }
115+ });
116+ } else {
117+ // Pass on errors that are not `kUnavailable`.
118+ encode_task (status);
119+ }
120+ }
74121}
75122
76123} // namespace
@@ -153,18 +200,20 @@ void ImageEncodingImpeller::ConvertImageToRaster(
153200 };
154201
155202 if (dl_image->owning_context () != DlImage::OwningContext::kRaster ) {
156- DoConvertImageToRasterImpeller (dl_image, std::move (encode_task),
157- is_gpu_disabled_sync_switch,
158- impeller_context);
203+ DoConvertImageToRasterImpellerWithRetry (dl_image, std::move (encode_task),
204+ is_gpu_disabled_sync_switch,
205+ impeller_context,
206+ /* retry_runner=*/ nullptr );
159207 return ;
160208 }
161209
162210 raster_task_runner->PostTask ([dl_image, encode_task = std::move (encode_task),
163211 io_task_runner, is_gpu_disabled_sync_switch,
164- impeller_context]() mutable {
165- DoConvertImageToRasterImpeller (dl_image, std::move (encode_task),
166- is_gpu_disabled_sync_switch,
167- impeller_context);
212+ impeller_context,
213+ raster_task_runner]() mutable {
214+ DoConvertImageToRasterImpellerWithRetry (
215+ dl_image, std::move (encode_task), is_gpu_disabled_sync_switch,
216+ impeller_context, raster_task_runner);
168217 });
169218}
170219
0 commit comments