Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistent SceneKit framerate

I'm seeing very inconsistent frame rates in the SceneKit starter project. Sometimes it runs constantly at 60 fps (12ms rendering, 6ms metal flush), and sometimes it runs constantly at 40 fps (20ms rendering, 6ms metal flush), no more, no less.

The frame rate changes randomly when I reopen the app, and will stay at that frame rate until the next reopen. I tried switching to OpenGL ES, and while it seems to fix it in the starter project, I still see those drops in my real app.

The starter project is unmodified (rotating ship), and I'm testing it on Xcode 7.0 and iPad Mini 4 running iOS 9.0.1. I'm not sure what is causing the problem, SceneKit, iOS or my device.

Edit: Here is a metal system trace, the first part it was running at 60fps, the second part I press the home button and reopen the app, and it runs at 40fps. It looks like there are a lot of color load/stores in the second part.

enter image description here

like image 270
Xzya Avatar asked Sep 28 '15 10:09

Xzya


1 Answers

Unfortunately it looks like SceneKit (and SpriteKit) are in evolutionary stages of development, at the expense of those using them.

This problem is definitely on all devices, and the following frameworks, that I know of:

  • SceneKit
  • SpriteKit
  • Metal

Even using OpenGL instead of Metal in the game frameworks the problem still exists, with no less consistency.

It looks to be an attempt by iOS to fix the frame rate at 40fps if iOS determines there's an issue maintaining a steady 60fps.

I think the cause of the drop to 40fps is iOS not being very good at interpreting "problems", and doing performance sampling over too short of a period at an unstable point in the app's launch, given many false positives for problems that aren't there once iOS itself has actually settled down and let the app/game run without hindrance.

The default template with the jetFighter shouldn't ever have trouble running at 60fps. So it only makes sense that this framerate cap "feature" would become active if the polling by iOS to determine when to cap the game loop at 40fps is done too early in the launch, for too short of a time. This means any interruption in the first few frames of the game causes iOS to cap it at 40fps, pre-emptively thinking the game won't/can't maintain 60fps.

Ironically, iOS is probably the cause of the hiccups it's detecting at the launch of the game that cause it to then consider the app unable to maintain a stable 60fps.

BUT I AM SPECULATING!

This is based on observation, not any known facts on the matter. But it's consistent with what I'm seeing happening and the only reasonable explanation I have so far.

The "good news" is iOS is not sampling only once and leaving it. It samples the game spasmodically, and after interruptions like jumping out to the home screen and back into the app.

For example: it's possible to cause a resampling of the framerate by iOS, and cause it to jump from 40 to 60, or 60 to 40, simply by starting Quicktime screenCapture whilst your device is connected. Apparently this (and a few other actions) will cause iOS to test the running app for its framerate consistency, again, then iOS adjusts according to its findings, again.

And, after an arbitrary amount of time, it scans again. If you leave the JetFighter template running for a while, you'll also see that eventually iOS does another test of the framerate consistency, and often determines that it's now stable enough at 60fps to put it back up to 60fps, despite having initially decided it should only run at 40fps.

I say all of this because I've watched a thing called "renderer" in the stats on the device deliberately taking up exactly the right amount of extra time in each gameloop to force 40fps, even when there's nowhere near enough other things going on to make that necessary.

It occurs to me that Apple is working on variable frame rate technology as per their statements about the iPad Pro, and the iOS features to support that have been (seemingly) implemented ahead of the release of the screen technology, and badly and oddly testing running apps to determine when to forcibly roll them down to slower frame rates.

Given that 40fps is an odd number not equally dividing into the default refresh rate of current devices at their 60fps refresh rate, it's likely the iPad Pro is capable of 120Hz screen refresh if they're so interested in 40fps.

When capturing from current iPads, if it's framerate locked at 40fps by iOS I'm seeing a 2:1:2:1:2:1 frame sequence that's how you'd make 40fps on a 60Hz refreshing device.

Which is in no way ideal. You wouldn't ever want to see this on a 60Hz screen because it's annoying, visually, even for people with insensitive eyes.

Possibly this variable framerate technology permits true 40fps on the new iPhones, I don't know. Haven't seen anything tested yet, but it does seem odd that something likely only truly possible on the iPad Pro is causing this issue on everything at the moment.

like image 189
Confused Avatar answered Nov 16 '22 00:11

Confused