iPhone 13 Pro High Refresh Rate Patch

If your games supports high refresh rate on iPad Pros, you don’t automatically get such on iPhone 13 Pro. Apple added a new API “preferredFrameRateRange” in CADisplayLink for developers to request a preferred range of frame rate to target instead of the previous “preferredFramesPerSecond” API, a single target. The reason for a range seems to be power management, that allowing for a lower frame rate would allow system to preserve power when it needs to. From my observation, even if the game request 120FPS minimum, the phone would occasionally flip back to 60FPS for a short period of time.

The following is the simplest modification needed in UnityAppController+Rendering.mm, but make sure you know what you are doing:

Before changing the code, add key “CADisableMinimumFrameDurationOnPhone” to Info.plist and set it to true.

- (void)callbackFramerateChange:(int)targetFPS
{
    int maxFPS = (int)[UIScreen mainScreen].maximumFramesPerSecond;
    if (targetFPS <= 0)
        targetFPS = UnityGetTargetFPS();
    if (targetFPS > maxFPS)
    {
        targetFPS = maxFPS;
        UnitySetTargetFPS(targetFPS);
        return;
    }

    _enableRunLoopAcceptInput = (targetFPS == maxFPS && UnityDeviceCPUCount() > 1);
   
    // PATCH START
    if (@available(iOS 15.0, *)) {
        _displayLink.preferredFrameRateRange = CAFrameRateRangeMake(targetFPS, targetFPS, targetFPS);
    } else {
        _displayLink.preferredFramesPerSecond = targetFPS;
    }
    // PATCH END
}
1 Like

Thanks for this, I was wondering how we could implement it.

I guess the real win would be if we could dynamically change the range depending on content (so for example on the pause menu it drops the fps a lot, to conserve battery), or have it as an option for the user to choose if they want 120fps or not, but that would require a well written plugin and that’ll take more effort and time than what I’m willing to spend right now.