Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Embedder] Only call removeview callback when raster thread is done with the view #164571

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

knopp
Copy link
Member

@knopp knopp commented Mar 4, 2025

Fixes #164564 (comment)

This would ensure that raster thread is completely done with the view, i.e. it won't try to use the opengl context, which might be associated with view window. So the client can know for sure, that when the callback returns, it is safe to destroy the view and container window.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard

This comment was marked as outdated.

@github-actions github-actions bot added the engine flutter/engine repository. See also e: labels. label Mar 4, 2025
@knopp knopp force-pushed the fix_remove_view_race branch 2 times, most recently from 7c315e7 to 5a238af Compare March 5, 2025 12:14
@knopp knopp changed the title WIP: [Embedder] Only call removeview callback when raster thread is done with the view [Embedder] Only call removeview callback when raster thread is done with the view Mar 5, 2025
@knopp knopp requested review from dkwingsmt and loic-sharma March 5, 2025 12:15
@knopp knopp force-pushed the fix_remove_view_race branch from ddcc3ad to 30c93ac Compare March 5, 2025 14:32
EmbedderConfigBuilder builder(context);
std::mutex engine_mutex;
UniqueEngine engine;
auto render_thread = CreateNewThread("custom_render_thread");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this mimicking the UI thread? Should we call it the UI thread instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mimicking raster thread:

builder.SetRenderTaskRunner(
      &render_task_runner.GetFlutterTaskRunnerDescription());

Copy link
Member

@loic-sharma loic-sharma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, but please also get an approval from @dkwingsmt if they have the cycles to review this.

Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!

@dkwingsmt
Copy link
Contributor

dkwingsmt commented Mar 11, 2025

Interestingly, I remember that the reason I had to make the callback earlier than the raster thread is because I must not let the main thread block on raster threads, which is further because macOS's rendering mechanism makes raster threads block on main threads (FlutterThreadSynchronizer). I clearly remember that this caused deadlock during my development. However, I've tested this PR on multiview mvp and no deadlock is observed. So I guess it works.

@knopp
Copy link
Member Author

knopp commented Mar 11, 2025

Interestingly, I remember that the reason I had to make the callback earlier than the raster thread is because I must not let the main thread block on raster threads, which is further because macOS's rendering mechanism makes raster threads block on main threads (FlutterThreadSynchronizer). I clearly remember that this caused deadlock during my development. However, I've tested this PR on multiview mvp and no deadlock is observed. So I guess it works.

To elaborate on that: MacOS no longer blocks the raster thread. But even if it did, the waiting would simply need to account for it. Linux for example will block the raster thread during present once it has separate raster thread, but we have way to ensure raster thread progress while blocking main thread, so this can be done without deadlocking. The callback will post a "unblock" message on main thread and the main thread will be pumping flutter messages (ignoring platform main thread messages) until the "unblock" message comes.

All desktop platforms now have resize synchronization implemented in unified way where we are able to only process flutter posted messages on main loop (ignoring other system messages). This makes it possible to block on RemoveView while ensuring raster thread progress.

@knopp knopp force-pushed the fix_remove_view_race branch from 4c538a5 to 25b73c0 Compare March 11, 2025 09:22
@dkwingsmt
Copy link
Contributor

Thank you for the explanation! That sounds great!

@dkwingsmt
Copy link
Contributor

(Feel free to add auto-submit when you feel ready.)

@knopp
Copy link
Member Author

knopp commented Mar 12, 2025

(Feel free to add auto-submit when you feel ready.)

I think want to test this on Linux first after separate raster thread landed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
engine flutter/engine repository. See also e: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FlutterEngineRemoveView may execute the callback too early
4 participants