-
Notifications
You must be signed in to change notification settings - Fork 6k
[macOS] Multi-view thread synchronizer #41915
[macOS] Multi-view thread synchronizer #41915
Conversation
|
Actually let me investigate if I can only halt one view's rendering instead of all views'. |
|
I think sharing the thread synchronizer is the way to go, but it should probably be aware of multiview. So the API should look maybe something like: @interface FlutterThreadSynchronizer : NSObject
- (void)view:(ViewId)viewId beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify;
- (void)view:(ViewId)viewId performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify;
- (void)viewShutDown:(ViewId)viewIdThe waiting for content size would become a Map<ViewId, CGSize>.
The |
|
@knopp Yeah, that's what I did in this PR. The method name is a little different, but I can switch to yours. I don't think shutdown should be tracked per view, because And after thinking for a while, I don't think it's possible to allow other views to rendering while one view is waiting for its correctly sized content. The rasterization for the view being resized has to fully complete before the next view can be resized, since after all the rasterization is not made async. However, this does not harm the experience at all, since the wait time should be minimal. All views continue their animation while the view is being resized. The remaining question is, can we add a unit test? I think it'll need multi-threading (multiple task queues), but I'm not familiar with it. Can you give me some ideas? |
| } | ||
|
|
||
| - (void)deregisterView:(int64_t)viewId { | ||
| _contentSizes.erase(viewId); |
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.
Is this meant to be called from platform thread? If not then maybe it should take the lock and notify _condBlockResize if it is actively waiting for content.
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've added assertion that this method is called from the platform thread.
|
My bad. The API seems fine, though I'm not sure what the cleanup process is. As for the tests, there are still just two threads, right? (platform and raster). I'd just use a serial background dispatch queue for simulating raster thread ( |
|
@knopp I've updated this PR and it should be ready for review. Changes include:
|
|
Also cc @cbracken might want to take a look as well. cc @loic-sharma since Windows might suffer from similar single-view assumption on a thread synchronizer. |
shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm
Show resolved
Hide resolved
knopp
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.
Some nits, otherwise LGTM!
shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h
Outdated
Show resolved
Hide resolved
shell/platform/darwin/macos/framework/Source/FlutterViewController.mm
Outdated
Show resolved
Hide resolved
|
auto label is removed for flutter/engine, pr: 41915, due to - The status or check suite Linux Web Framework tests has failed. Please fix the issues identified (or deflake) before re-applying this label. |
…127633) flutter/engine@ff04d2f...f4dc96a 2023-05-25 [email protected] [macOS] Multi-view thread synchronizer (flutter/engine#41915) 2023-05-25 [email protected] Roll Dart SDK from 0e78305875a4 to 5697e9123611 (1 revision) (flutter/engine#42327) 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 [email protected],[email protected],[email protected] 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://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This PR adapts
FlutterThreadSynchronizerto multi-view.Problem
The
FlutterThreadSynchronizeris a macOS engine class to ensure that, if the current window is resized, nothing will not be presented until the layer tree is drawn with the up-to-date size.This class is not compatible with multiview. A simple way to realize it is: while the class is owned by
FlutterView, it blocks the global platform thread and rasterizer thread - there is got to be some problems. Indeed, when I was testing with multiple windows (#40399), the app freezes as soon as I resize a window.The problem is because Flutter only have one rasterizer thread. When I'm resizing window A, A's synchronizer detects that the size mismatches, so it blocks the rasterizer thread to wait for an updated content with the updated size. However, window B is to be rendered next, and B's size matches and will try to rasterize, and will be blocked due to the blocked rasterizer thread, window A's updated content will never arrive, causing a deadlock.
Changes
This PR removes the single-view assumption of
FlutterThreadSynchronizerby making it created byFlutterEngineand shared by allFlutterViews, and that it prevents rasterization for all views if any view has a mismatched size.The synchronizer is assigned to the view controller in the
attachToEngine:withIdmethod (now renamed tosetUpWithEngine:viewId:threadSynchronizer:.This PR also adds unit tests for
FlutterThreadSynchronizer, which didn't have any unit tests at all.beginResizeForView:method no longer checks whether is called on the main thread, but whether it's called on the main queue. These are equivalent for the real main queue, since the documentation promises that the main queue always executes on the main thread. However, this change allows substituting the queue with a custom one for unit tests.Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.