Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 4189a33

Browse files
committed
Move VSyncWaiter to engien to simplify locking
1 parent 8482de0 commit 4189a33

File tree

4 files changed

+34
-18
lines changed

4 files changed

+34
-18
lines changed

shell/platform/darwin/macos/framework/Source/FlutterEngine.mm

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h"
2323
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
2424
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h"
25+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiter.h"
2526
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
2627
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"
2728

@@ -459,6 +460,10 @@ @implementation FlutterEngine {
459460

460461
// Proxy to allow plugins, channels to hold a weak reference to the binary messenger (self).
461462
FlutterBinaryMessengerRelay* _binaryMessenger;
463+
464+
// Map from ViewId to vsync waiter. Note that this is modified on main thread
465+
// but accessed on UI thread, so access must be @synchronized.
466+
NSMapTable<NSNumber*, FlutterVSyncWaiter*>* _vsyncWaiters;
462467
}
463468

464469
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project {
@@ -528,6 +533,8 @@ - (instancetype)initWithName:(NSString*)labelPrefix
528533
_terminationHandler = nil;
529534
}
530535

536+
_vsyncWaiters = [NSMapTable strongToStrongObjectsMapTable];
537+
531538
return self;
532539
}
533540

@@ -721,6 +728,22 @@ - (void)registerViewController:(FlutterViewController*)controller forId:(Flutter
721728
[controller setUpWithEngine:self viewId:viewId threadSynchronizer:_threadSynchronizer];
722729
NSAssert(controller.viewId == viewId, @"Failed to assign view ID.");
723730
[_viewControllers setObject:controller forKey:@(viewId)];
731+
732+
__weak FlutterEngine* weakSelf = self;
733+
FlutterVSyncWaiter* waiter = [[FlutterVSyncWaiter alloc]
734+
initWithView:controller.view
735+
block:^(CFTimeInterval timestamp, CFTimeInterval targetTimestamp, uintptr_t baton) {
736+
// CAMediaTime and flutter time are both mach_absolute_time.
737+
uint64_t timeNanos = timestamp * 1000000000;
738+
uint64_t targetTimeNanos = targetTimestamp * 1000000000;
739+
FlutterEngine* engine = weakSelf;
740+
if (engine) {
741+
engine->_embedderAPI.OnVsync(_engine, baton, timeNanos, targetTimeNanos);
742+
}
743+
}];
744+
@synchronized(_vsyncWaiters) {
745+
[_vsyncWaiters setObject:waiter forKey:@(viewId)];
746+
}
724747
}
725748

726749
- (void)deregisterViewControllerForId:(FlutterViewId)viewId {
@@ -729,6 +752,9 @@ - (void)deregisterViewControllerForId:(FlutterViewId)viewId {
729752
[oldController detachFromEngine];
730753
[_viewControllers removeObjectForKey:@(viewId)];
731754
}
755+
@synchronized(_vsyncWaiters) {
756+
[_vsyncWaiters removeObjectForKey:@(viewId)];
757+
}
732758
}
733759

734760
- (void)shutDownIfNeeded {
@@ -1048,21 +1074,14 @@ - (void)engineCallbackOnPreEngineRestart {
10481074
}
10491075

10501076
- (void)onVSync:(uintptr_t)baton {
1051-
FlutterViewController* controller = [self viewControllerForId:kFlutterImplicitViewId];
1052-
if (controller) {
1053-
[controller waitForVSync:baton];
1077+
@synchronized(_vsyncWaiters) {
1078+
FlutterVSyncWaiter* waiter = [_vsyncWaiters objectForKey:@(kFlutterImplicitViewId)];
1079+
if (waiter) {
1080+
[waiter waitForVSync:baton];
1081+
}
10541082
}
10551083
}
10561084

1057-
- (void)onVSyncWithTimestamp:(CFTimeInterval)timestamp
1058-
targetTimestamp:(CFTimeInterval)targetTimestamp
1059-
baton:(uintptr_t)baton {
1060-
// CAMediaTime and flutter time are both mach_absolute_time.
1061-
uint64_t timeNanos = timestamp * 1000000000;
1062-
uint64_t targetTimeNanos = targetTimestamp * 1000000000;
1063-
_embedderAPI.OnVsync(_engine, baton, timeNanos, targetTimeNanos);
1064-
}
1065-
10661085
/**
10671086
* Note: Called from dealloc. Should not use accessors or other methods.
10681087
*/

shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,6 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) {
212212
- (void)announceAccessibilityMessage:(NSString*)message
213213
withPriority:(NSAccessibilityPriorityLevel)priority;
214214

215-
- (void)onVSyncWithTimestamp:(CFTimeInterval)timestamp
216-
targetTimestamp:(CFTimeInterval)targetTimestamp
217-
baton:(uintptr_t)baton;
218-
219215
@end
220216

221217
@interface FlutterEngine (Tests)

shell/platform/darwin/macos/framework/Source/FlutterVSyncWaiter.mm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ - (void)waitForVSync:(uintptr_t)baton {
136136
}
137137

138138
- (void)dealloc {
139+
if (_pending_baton.has_value()) {
140+
FML_LOG(WARNING) << "Deallocating FlutterVSyncWaiter with a pending vsync";
141+
}
139142
[_displayLink invalidate];
140143
}
141144

shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@
6767
*/
6868
- (void)updateSemantics:(nonnull const FlutterSemanticsUpdate2*)update;
6969

70-
- (void)waitForVSync:(uintptr_t)baton;
71-
7270
@end
7371

7472
// Private methods made visible for testing

0 commit comments

Comments
 (0)