mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
cocoa_common: report panel refresh rate, not our own display link rate
cocoa_get_refresh_rate() on iOS/tvOS returned the CADisplayLink's
preferredFrameRateRange.preferred. Since 12c4ff0739 ("apple: better
refresh rate restoration") apple_display_server_init() stamps
settings->floats.video_refresh_rate onto that same display link at
startup, so the getter and the setter now share one storage slot.
The result is a feedback loop. DEFAULT_REFRESH_RATE is 60 on Apple
targets, so on a fresh config the display link is pulled from the
panel rate the CocoaView set up ([UIScreen maximumFramesPerSecond],
120 on ProMotion) down to 60, and every subsequent read reports 60.
"Set Display-Reported Refresh Rate" can therefore never report
anything the user does not already have configured, and on a
ProMotion iPhone it is stuck at 60 Hz.
All four Apple refresh-rate vtable entries (cocoa_gl_ctx,
cocoa_vk_ctx, metal, dispserv_apple) funnel into this helper, so the
stale value also reaches runloop.c's vsync throttle decision and
RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE.
Query [UIScreen maximumFramesPerSecond] instead. That is the
iOS/tvOS analogue of the CGDisplayModeGetRefreshRate() call the macOS
branch of this same function already makes: a property of the
display, not of our own timer. The display link is kept only as the
pre-iOS-10.3 fallback, where maximumFramesPerSecond does not exist
and no ProMotion hardware does either.
The display link keeps honouring the configured rate for actual
frame pacing; only the reporting path changes.
This commit is contained in:
1 parent
79b46b2518
commit
580c738efd
1 file changed
+35
-24
@@ -1161,33 +1161,44 @@ float cocoa_get_refresh_rate(void)
|
||||
return (rate > 0.0) ? (float)rate : 60.0f;
|
||||
#endif
|
||||
#else /* iOS / tvOS */
|
||||
CADisplayLink *dl = [CocoaView get].displayLink;
|
||||
if (dl)
|
||||
{
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 || __TV_OS_VERSION_MAX_ALLOWED >= 150000
|
||||
if (@available(iOS 15.0, tvOS 15.0, *))
|
||||
return dl.preferredFrameRateRange.preferred;
|
||||
#endif
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __TV_OS_VERSION_MAX_ALLOWED >= 100000
|
||||
if (@available(iOS 10.0, tvOS 10.0, *))
|
||||
return dl.preferredFramesPerSecond;
|
||||
#endif
|
||||
/* iOS 6 - 9 / tvOS < 10: only frameInterval exists. It is
|
||||
* the number of screen refreshes between callbacks, so
|
||||
* convert to Hz assuming a 60 Hz panel (accurate for every
|
||||
* pre-iOS-10 device - ProMotion is iPad Pro 2017+). */
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
{
|
||||
NSInteger fi = dl.frameInterval;
|
||||
return 60.0f / (float)(fi > 0 ? fi : 1);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
/* Report what the panel is capable of, NOT what we last asked
|
||||
* the CADisplayLink to run at.
|
||||
*
|
||||
* apple_display_server_init() stamps
|
||||
* settings->floats.video_refresh_rate onto the display link at
|
||||
* startup, so querying preferredFrameRateRange here closes a
|
||||
* feedback loop: "Set Display-Reported Refresh Rate" would just
|
||||
* echo the value the user already has configured. On a
|
||||
* ProMotion device with a default config that means a permanent
|
||||
* 60 Hz readout even though the panel does 120 Hz.
|
||||
*
|
||||
* maximumFramesPerSecond is the iOS/tvOS analogue of the
|
||||
* CGDisplayModeGetRefreshRate() query the macOS branch above
|
||||
* makes - a property of the display, not of our own timer. */
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100300 || __TV_OS_VERSION_MAX_ALLOWED >= 100200
|
||||
if (@available(iOS 10.3, tvOS 10.2, *))
|
||||
return [UIScreen mainScreen].maximumFramesPerSecond;
|
||||
{
|
||||
NSInteger max_fps = [[UIScreen mainScreen] maximumFramesPerSecond];
|
||||
if (max_fps > 0)
|
||||
return (float)max_fps;
|
||||
}
|
||||
#endif
|
||||
/* iOS 6 - 9 / tvOS < 10: maximumFramesPerSecond does not exist.
|
||||
* Only CADisplayLink's frameInterval does - the number of screen
|
||||
* refreshes between callbacks - so convert to Hz assuming a 60 Hz
|
||||
* panel (accurate for every pre-iOS-10 device; ProMotion is iPad
|
||||
* Pro 2017 / iOS 10.3+). */
|
||||
{
|
||||
CADisplayLink *dl = [[CocoaView get] displayLink];
|
||||
if (dl)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
NSInteger fi = [dl frameInterval];
|
||||
#pragma clang diagnostic pop
|
||||
return 60.0f / (float)(fi > 0 ? fi : 1);
|
||||
}
|
||||
}
|
||||
return 60.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user