engine icon indicating copy to clipboard operation
engine copied to clipboard

[engine] support combined UI/Platform thread for iOS/Android.

Open jonahwilliams opened this issue 1 year ago • 3 comments

Experimentally support merging UI and platform thread on Android/iOS. This works by changing the shell holder to set the UI thread to the platform thread. Several shell APIs that post messages from the platform to ui thread were changed to use RunNowOrPostTask to immediately call the UI task if the threads are the same.

Experimentally, this seems to work reasonably well if there are no platform views. On Android with TLHC it works fine either way, while iOS currently takes a big performance hit.

This can be opted into via a Plist:

	<key>FLTEnableMergedPlatformUIThread</key>
	<true/>

Or via AndroidManifest.xml:

 <meta-data
            android:name="io.flutter.embedding.android.EnableMergedPlatformUIThread"
            android:value="true" />

https://github.com/flutter/flutter/issues/150525

jonahwilliams avatar Jun 30 '24 02:06 jonahwilliams

The tester shells are already running in a combined thead mode (unless run with --force-multithreading).

It is easy to go merge the threads but there is no going back because of plugins.

Adding an experimental option that we don't advertise is not a one way door. Anyone that ships code that depends on this behavior can be broken

jonahwilliams avatar Jul 01 '24 18:07 jonahwilliams

I love this! I'll try to get this working on macOS with the resize synchronizer, but I'm not sure how much time I'm going to have this week (FlutterCon).

Btw. the io.flutter.1.ui thread still gets created, just sitting there empty.

knopp avatar Jul 01 '24 20:07 knopp

I have a very fragile and buggy but working macOS proof of concept working. The idea is to short-circuit macOS vsync waiter during resizing to fire immediately, and then to modify the vsync waiter machinery in the engine so that if the vsync callback is called from UI thread and frame_start_time is in past, it will trigger the frame immediately instead.

knopp avatar Jul 02 '24 21:07 knopp

Btw. the io.flutter.1.ui thread still gets created, just sitting there empty.

Should be fixed now.

jonahwilliams avatar Jul 03 '24 23:07 jonahwilliams

I've a WIP PR for macos here. Some remaining open questions there, mostly regarding the microtask queue.

knopp avatar Jul 07 '24 15:07 knopp

@chinmaygarde do you intend to review this patch?

jonahwilliams avatar Jul 08 '24 22:07 jonahwilliams

I simply can't agree that an experimental flag presents an opportunity for ecosystem breakage. I agree that we should good answers for the question of performance before we make this the default behavior, but opting in for testing and experimentation is well within the realm of changes like platform isolates, wide gamut, impeller, et cetera.

jonahwilliams avatar Jul 08 '24 23:07 jonahwilliams

If the plugin assumes merged UI and platform thread, it would mean that the plugin imposes the flag on the end user, which I don't really like. For example with super_drag_and_drop and super_clipboard, I make quite a few assumptions about threading (I routinely need to pause platform thread to while getting answer from UI thread). I plan to support merged threads as soon as it lands on all platforms, but as an addition to the default threading model, and not exclusively.

I think we need to communicate this clearly that if plugins make threading assumptions, they need to support both models for the time being, and never force the flag on end user.

knopp avatar Jul 09 '24 18:07 knopp

I am not sure you can force plugin authors to support both models. Exposing to plugins which model is being used then asking nicely might be your only option. If you let plugin authors detect the threading model and let the apps set the threading model then plugin authors can choose how to handle the difference. Plugins that dont care can Ignore the change, some will support both, some can throw exceptions or can use the thread model to enable or disable a subset of features.

reidbaker avatar Jul 09 '24 19:07 reidbaker

To be clear, this flag is for our own experimentation.

There is absoltely no plan to make this a configurable option for developers. Either we find a means to merge the platform and ui threads, in general, and make that the only default behavior, or we don't.

I'm not currently aware of any circumstances where moving from un merged to merged thread model will break any plugins, but this is something that I hope to discover this quarter. (I could certainly see the opposite breaking plugins, but that won't be a configurable option)

jonahwilliams avatar Jul 09 '24 19:07 jonahwilliams

This will absolutely cause super_drag_and_drop to deadlock, since it needs to respond to synchronous platform callbacks and it does it by carefully blocking the platform thread until it has response from UI thread. But I also think this is a very uncommon scenario.

knopp avatar Jul 09 '24 19:07 knopp

Assuming we had a solution to the other thread merging problems, I'd like us to handle that with some like "Starting from (Future) version 3.XX, threads will be merged, if you do X/Y/Z instead do A/B/C" instead of letting folks opt in or out.

jonahwilliams avatar Jul 09 '24 19:07 jonahwilliams