I have a problem though. Sometimes the app runs perfectly at 120hz/fps then suddenly and randomly it gets locked to 60fps. Sometimes it gets unlocked to 120fps again.
In profiler it shows that time got spent on Gfx.WaitForPresentOnGfxThread, on display synchronisation or waiting for GPU. One can assume that it is a GPU performance issue but Xcode Profiler shows a different picture:
Here are stats when it runs at 120fps. Perfect!
And now when it locks to 60fps. Notice very low GPU and CPU load.
I’m using Unity 2020.3.33f1, it also does this on newer 2021.* versions
It happens totally randomly. Neither battery level of the phone, neither quality settings inside the app affects this. ProMotion is enabled in player’s settings.
Thanks, Neonlyte! Don’t know if it is an Apple’s issue. The game Thumper on iOS for example doesn’t have this problem and can run at 120hz steadily and it wasn’t made in Unity engine. Maybe they used some hack with UIView animations or something to force iOS to run at 120hz.
I’m also meeting this bug here with iPad Pro 2021. Exactly the same behavior. Normally my stuff is done within 1ms, and the profiler shows 1ms stuff and 6ms WaitForTargetFPS. But suddenly it gets through 60fps, or even spikes to 30fps occasionally. It is really weird.
After a bit of digging I found that the code for synchronization is visible in the XCode project, search for preferredFrameRateRange – you can find that in a #if ios 15 block.
I currently didn’t find any information about how the dirty iOS internals govern the frame rates. I checked info.plist and the .mm files and unity seems to be doing nothing wrong.
Not sure if related, but in my game I have nasty frame drops specifically on iPhone 13 pro.
I have Application.targetFrameRate set to 60, and it works fine on older devices: iPhone11, iPhone XR, and even iPhone SE (2016). But on iPhone 13 pro there is a periodic (~ once per second) frame drop from 60 to 40s, and a noticeable hiccup. I haven’t profiled it all yet, and not sure if 100% related to this thread, but at least it’s the closest one I found so far.
Ok, just digged a bit deeper. The issue in my case is also with Gfx.WaitForPresentOnGfxThread. Although, the manifestation is different, instead of randomly dropping to some other frame-rate, I see crippling spike every 60th frame. Below are three screenshots of the profiler with some comments
First a “normal” frame. It’s the same picture that I can see on iPhone 11 and iPhone XR: solid 16.5 ms (60 FPS) with most of the time spend in the WaitForTargetFPS.
An update. One thing that I must have mentioned is that in my case I was using URP pipeline for iOS. At the beginning I wasn’t relating the problem with the render, however, then I found this thread Gfx.WaitForPresentOnGfxThread takes long time and decided to just give it a try, and migrate to “legacy” built-in render pipeline. Miraculously, it worked, there are no spikes in URP on iPhone 13Pro or other devices.
+1, I’m having the exact same issue. I’ve got a 13 Pro Max with precicely what you’re describing here. I’m using Unity 2021.3.5f1 with the latest version of the URP. My heart sank when I saw how recent all of this was… hopefully they get it sorted soon. I voted on the issue on issuetracker.
I would like to have answers on why this problem is not fixable. Your explanation that it is performance issue doesn’t count because this problem happens even in empty projects. Are there plans to fix it in a future?
I just messed around with Unity’s Metal support code in the generated Xcode project. Try comment out the following code below and see if the 120FPS is stable for you. My reproduction project could maintain it easily (I did switch to use iPhone 14 Pro, so I am not sure what the behavior for 13 Pro would be):
Edit: I may have spoken too early. I did just see the reproduction project dip to 60, although not as often as before. I still do think this is because of the device difference, unless people here can test it for me.
Any updates? Same issue, it’s special for 120hz I guess. I tried with 90 (but it limited with 80) and its working much better than 120. Still dipping 60 but not as often as before.