mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
cocoa_common: prefer panel refresh rate over our own display link rate
cocoa_get_refresh_rate() on iOS/tvOS reads the CADisplayLink's own preferred rate. Since12c4ff0739("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 share one storage slot. That closes a feedback loop. DEFAULT_REFRESH_RATE is 60 on Apple targets, so on a fresh config the link is pulled from the panel rate the CocoaView set it up with ([UIScreen maximumFramesPerSecond], 120 on ProMotion) down to 60, and every later read reports 60. "Set Display-Reported Refresh Rate" can therefore never report anything the user does not already have configured; on a ProMotion iPhone it is pinned 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] first. 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. This is strictly additive. An earlier attempt at this fix (580c738efd, reverted in6ec192c883) replaced the fallback ladder instead of extending it, which stranded iOS 10.0 - 10.2 on deprecated frameInterval even though preferredFramesPerSecond covers it. Here the new query is one more rung on top and nothing below it is touched: 10.3+ / tvOS 10.2+ maximumFramesPerSecond (new, SDK + @available) 15.0+ preferredFrameRateRange (unchanged) 10.0+ preferredFramesPerSecond (unchanged) < 10.0 frameInterval (unchanged) no display link maximumFramesPerSecond (unchanged) otherwise 60.0f (unchanged) The new rung is guarded by both __IPHONE_OS_VERSION_MAX_ALLOWED / __TV_OS_VERSION_MAX_ALLOWED and a runtime @available, so pre-10.3 SDKs do not see the selector and pre-10.3 devices do not call it. maximumFramesPerSecond is known to answer 0 on some simulators, so a non-positive result falls through to the ladder rather than being returned. A 0 result with no display link present still returns 0 exactly as before, which video_driver_get_refresh_rate() reads as "unsupported" and resolves from config. The existing ladder is now wrapped in a block so that its CADisplayLink declaration stays at block top; that reindent is the only reason this diff shows deletions. `git diff -w` against the parent removes nothing. The display link keeps honouring the configured rate for actual frame pacing; only the reporting path changes.
This commit is contained in:
1 parent
6ec192c883
commit
fde942cba9
1 file changed
+44
-14
@@ -1161,28 +1161,58 @@ 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)
|
||||
/* Prefer the panel's own capability over the CADisplayLink's
|
||||
* preferred rate.
|
||||
*
|
||||
* apple_display_server_init() stamps
|
||||
* settings->floats.video_refresh_rate onto the display link at
|
||||
* startup, so reading that link back here closes a feedback
|
||||
* loop: "Set Display-Reported Refresh Rate" only ever echoes the
|
||||
* value the user already has configured, and a ProMotion panel
|
||||
* reports 60 Hz forever because 60 is DEFAULT_REFRESH_RATE.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* It only exists on iOS 10.3 / tvOS 10.2, and it is known to
|
||||
* answer 0 on some simulators, so this is an extra rung on top
|
||||
* of the ladder rather than a replacement for it. Every path
|
||||
* below stays reachable and unchanged: 10.0 - 10.2 still gets
|
||||
* preferredFramesPerSecond, pre-10.0 still gets frameInterval,
|
||||
* and a 0 answer here still falls through to them. */
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100300 || __TV_OS_VERSION_MAX_ALLOWED >= 100200
|
||||
if (@available(iOS 10.3, tvOS 10.2, *))
|
||||
{
|
||||
NSInteger max_fps = [[UIScreen mainScreen] maximumFramesPerSecond];
|
||||
if (max_fps > 0)
|
||||
return (float)max_fps;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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+). */
|
||||
/* 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);
|
||||
}
|
||||
{
|
||||
NSInteger fi = dl.frameInterval;
|
||||
return 60.0f / (float)(fi > 0 ? fi : 1);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100300 || __TV_OS_VERSION_MAX_ALLOWED >= 100200
|
||||
if (@available(iOS 10.3, tvOS 10.2, *))
|
||||
|
||||
Reference in new issue
Block a user