-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] implements a retry mechanism for dart:ui/Image.toByteData. #46840
Conversation
556afdd to
234fcd7
Compare
|
|
||
| void ContextMTL::StoreTaskForGPU(std::function<void()> task) { | ||
| tasks_awaiting_gpu_.emplace_back(std::move(task)); | ||
| while (tasks_awaiting_gpu_.size() > kMaxTasksAwaitingGPU) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a maximum limit of tasks? If we do have a limit, do we need a mechanism to drop them gracefully?
For example, if there is a Future pending from toByteData, I'd think that dropping the task should cause an error to be thrown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EncodeImageFailsWithoutGPUImpeller tests this, it's handled gracefully since you have to check for the GPU in the callback and we never retry more than once. Getting dropped is just like the behavior we had before we implemented the retry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, so when we exceed the size we execute the task, and then the task sees the GPU is still unavailable and errors? makes sense. I would document that a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added that info to the Context::StoreTaskForGPU docstring.
| if (!status.ok()) { | ||
| if (status.code() == fml::StatusCode::kUnavailable) { | ||
| impeller_context->StoreTaskForGPU( | ||
| [dl_image, encode_task = std::move(encode_task), | ||
| is_gpu_disabled_sync_switch, impeller_context, | ||
| retry_runner]() mutable { | ||
| auto retry_task = [dl_image, encode_task = std::move(encode_task), | ||
| is_gpu_disabled_sync_switch, impeller_context] { | ||
| fml::Status retry_status = DoConvertImageToRasterImpeller( | ||
| dl_image, encode_task, is_gpu_disabled_sync_switch, | ||
| impeller_context); | ||
| if (!retry_status.ok()) { | ||
| encode_task(retry_status); | ||
| } | ||
| }; | ||
| if (retry_runner) { | ||
| retry_runner->PostTask(retry_task); | ||
| } else { | ||
| retry_task(); | ||
| } | ||
| }); | ||
| } else { | ||
| encode_task(status); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is a little hard to read. Are we dropping the status here in the event its not OK and the code isn't unavailable, or does that percolate up elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some comments. Let me know if you think this is the right amount and if it is helpful.
46f0dde to
cd38f20
Compare
|
|
||
| /// The maximum number of tasks that should ever be stored for | ||
| /// `StoreTaskForGPU`. | ||
| static constexpr int32_t kMaxTasksAwaitingGPU = 10; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh by the way. I'm open to increasing this. I just pulled this number out of nowhere but I knew I didn't want it to be completely unbounded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would leave a note that this was arbitrarily chosen so we're not afraid to increase it in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
jonahwilliams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
Turns out some tests were using nullptr for the syncswitch when it shouldn't. I've updated the test. Those tests are a pain to debug. |
…136665) flutter/engine@ca8cf6b...c24f303 2023-10-16 skia-flutter-autoroll@skia.org Roll Skia from 675f088b9ac4 to 68de6e352585 (1 revision) (flutter/engine#46956) 2023-10-16 30870216+gaaclarke@users.noreply.github.com [Impeller] implements a retry mechanism for dart:ui/Image.toByteData. (flutter/engine#46840) 2023-10-16 jason-simmons@users.noreply.github.com [Impeller] Adjust clip coverage operations to handle per-pass clip stacks (flutter/engine#46912) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…#46840) Design doc: [link](https://docs.google.com/document/d/1Uuiw3pdQxNFTA8OQuZ-kuvYg1NB42XgccQCZeqr4oII/edit#heading=h.hn6wreyrz6fm) fixes: flutter/flutter#135245 One slight deviation from the design doc is that I decided to make ContextMTL respond to changes to the SyncSwitch instead of having it observe the app state directly. The benefits are: 1) This keeps that functionality in one location 1) It makes writing tests much easier 1) There's no need of conditional compilation between macos and ios 1) There is no need to add an objc class [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Design doc: link
fixes: flutter/flutter#135245
One slight deviation from the design doc is that I decided to make ContextMTL respond to changes to the SyncSwitch instead of having it observe the app state directly. The benefits are:
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.