Search Issue Tracker

Won't Fix

Votes

5

Found in

5.3.5p1

Issue ID

795628

Regression

Yes

[iOS] Gfx.WaitForPresent spikes on Metal every few minutes

iOS

-

How to reproduce:

1. Open attached project
2. Build to iOS and run
3. Connect the Unity profiler to the device
4. Observe the graph in the profiler as well as the cube movement in the device
- Note how approximately every two minutes, the screen pauses for just a frame, with a corresponding spike in the profiler with Gfx.WaitForPresent taking up over 90% of CPU time
- The spikes happen in the profiler even without a screen pause about once every 30 seconds

- Reproduced in Version 5.4.0b19 (57f24ff20089), Version 5.3.5p1 (c851d0cdbe93) on an iPhone 5S (iOS 9.2.1), iPhone 6+ (9.3.1) only spikes, no screen stuttering
- Not reproducible in Version 5.2.4f1 (98095704e6fe)

RESOLUTION:

WONTFIX, the explanation is below:

I have investigated the issue and it looks like a known problem with iOS in general. Unfortunately there's not much we can do to solve it.

The explanation for the observed behavior is that iOS reduces the CPU and GPU speed in order to save power. For games, if, say, 60fps (=16.6ms per frame) is targeted, less power is used whenever CPU/GPU speed is reduced so that just less than 16ms is used for a frame. For example, more power is used if the processor is twice as fast and processes a frame in only 8ms and spends the rest of time sleeping.

As a result, regardless of scene complexity, iOS will always make a game spend 16ms per frame (well, unless the scene is so simple that the CPU is always in lowest power state). If the scene complexity changes just a little bit, it may happen that the rendering takes more than 16.6ms and we miss vsync. So when we finish rendering, we submit the frame to be diplayed as N+1 frame. Immediately after that we start rendering N+1 frame, but when we finish, the N+1 slot is taken and we can only submit the frame as N+2. Eventually iOS notices (it may happen after a frame or two) and does not allow this one frame delay to continue. It solves it by delaying CAMetalLayer nextDrawable call. This is what is seen as Gfx.WaitForPresent.

On some projects with just a little bit more variable scenes it is much more evident in the profiler graph that whenever a frame is missed, iOS takes note of that and puts CPU in higher power state for subsequent second or two. I've been able to create a reproduction project in which we could obserse frame time gradually increase from 8ms to 16ms as iOS downclocked the CPU and then after the frame time exceeded 16ms for a frame or two, it returned back to 8ms as iOS clocked the CPU faster.

Comments (5)

  1. Tyberious

    Oct 12, 2016 12:49

    To further this DX9 and Open GL it does not occur but DX11 and DX12 it does.

  2. Tyberious

    Oct 12, 2016 12:48

    We are having this issue as well and switching to Open GL also resolves it. It has to be a bug of some kind.

  3. Akta

    Sep 09, 2016 14:29

    I can confirm this happens on Unity 5.4.1, no stuggering noticeable unless you start panning the camera around, in that case you can notice that the movement is not smooth as it should be. Happens randomly and goes on and off, I temporarily solved the issue forcing the rendering API to be OGLES 2.

  4. ottolb

    Jul 13, 2016 13:05

    Hi, we still getting this bug on latest betas (24/25).
    Here is the project link for those who are interested: https://dl.dropboxusercontent.com/u/37438884/Cube.zip

  5. amoraleite

    Jul 13, 2016 13:03

    Were is the project? Thank you!

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.