19 void (^_callback)(CFTimeInterval startTime, CFTimeInterval targetTime);
25 isVariableRefreshRateEnabled:(
BOOL)isVariableRefreshRateEnabled
26 maxRefreshRate:(
double)maxRefreshRate
27 callback:(
void (^)(CFTimeInterval startTime,
28 CFTimeInterval targetTime))callback {
29 NSAssert(
callback,
@"callback must not be nil");
30 NSAssert(taskRunner,
@"taskRunner must not be nil");
32 if (
self = [super init]) {
33 _refreshRate = maxRefreshRate;
35 _allowPauseAfterVsync = YES;
37 _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onDisplayLink:)];
40 [
self setMaxRefreshRate:maxRefreshRate];
48 [strongSelf.displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
56- (void)setMaxRefreshRate:(
double)refreshRate {
62 if (@available(iOS 15.0, *)) {
64 CAFrameRateRangeMake(minFrameRate, maxFrameRate, maxFrameRate);
78- (void)onDisplayLink:(CADisplayLink*)link {
88 CFTimeInterval timestamp = link.timestamp;
89 if (timestamp == 0.0) {
90 timestamp = CACurrentMediaTime();
96 CFTimeInterval targetTimestamp = link.targetTimestamp;
97 if (targetTimestamp <= timestamp) {
99 targetTimestamp = timestamp + (1.0 / effectiveRefreshRate);
101 CFTimeInterval duration = targetTimestamp - timestamp;
112 double roundedRefreshRate = round(1.0 / duration);
113 if (roundedRefreshRate > 0.0) {
114 _refreshRate = roundedRefreshRate;
118 if (_allowPauseAfterVsync) {
121 _callback(timestamp, targetTimestamp);
129 [_displayLink invalidate];
133- (CADisplayLink*)displayLink {
152 CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:[[[
self class] alloc] init]
153 selector:@selector(onDisplayLink:)];
154 displayLink.paused = YES;
155 NSInteger preferredFPS = displayLink.preferredFramesPerSecond;
162 if (preferredFPS != 0) {
166 return UIScreen.mainScreen.maximumFramesPerSecond;
169- (void)onDisplayLink:(CADisplayLink*)link {
174 return [[NSBundle.mainBundle objectForInfoDictionaryKey:kCADisableMinimumFrameDurationOnPhoneKey]
CADisplayLink * _displayLink
BOOL _isVariableRefreshRateEnabled
FLUTTER_ASSERT_ARC NSString *const kCADisableMinimumFrameDurationOnPhoneKey
Info.plist key enabling the full range of ProMotion refresh rates for CADisplayLink callbacks and CAA...
static const double kDefaultRefreshRate
FlutterDesktopBinaryReply callback
A manager type that queries display characteristics, such as high refresh rate capabilities.
BOOL maxRefreshRateEnabledOnIPhone
Whether the max refresh rate on iPhone ProMotion devices are enabled. This reflects the value of CADi...
double displayRefreshRate
The maximum display refresh rate used for reporting purposes. This is intended to return either the h...
void postTask:(void(^ task)(void))
void tracePlatformVsyncWithStartTime:targetTime:(NSTimeInterval startTime,[targetTime] NSTimeInterval targetTime)
A client that wraps a CADisplayLink to deliver synchronized vsync signals.