So I've got a weird issue. I'm porting a modern source port of an old game engine to iOS and tvOS. It was written using OpenGL and I found a fork of it that uses OpenGL ES and I've been able to Frankenstein combine the two to where it will actually now successfully run on iOS and tvOS devices.
Here's the weird part - parts of the game do not render correctly on my iPhone X but they do render correctly on my iPad Air 2 and Apple TV (4th gen).
I notice in the flurry of messages in the output window that the spot where the engine outputs renderer information, on the iPhone X it says
OpenGL version: OpenGL ES 2.0 Metal 58.4
whereas on, say, the iPad Air 2 it says
OpenGL version: OpenGL ES 2.0 A8X GPU - 130.1
"OpenGL ES Metal" sounds like "Jumbo Shrimp" to me since those are obviously not the same thing. If I were to guess, I'd say that on the iPhone X the OpenGL ES drivers are running on top of some sort of Metal translation layer, which may be Apple's long term plan for having some sort of future-proofing in the wake of the OpenGL ES deprecation.
But for whatever reason it's breaking my game engine and although I'm decent at making code work together, I don't know enough about graphics coding to know even where to look to change things to work.
Obviously the right answer is to fix whatever is causing the issue but as a short term fix I'm curious if there's any way to get a game on iOS to not use OpenGL ES on top of Metal? (if that is indeed what is happening)
So, like Brad Larson says below, the answers were: yes OpenGL ES is running on top of Metal and no, it can't be avoided. However for future reference if anyone else is running into this problem I solved the real underlying issue with the help of another SO answer:
WebGL GLSL fragment shader not working on iOS
Basically the floating point precision of the shaders need to be upgraded from lowp
and mediump
to highp
Yes, OpenGL ES is effectively an interface to Metal on recent iOS versions (since I believe 10, if I'm not mistaken).
From the Roblox Metal retrospective:
It is also worth noting that there is no GL driver on iOS 10 on the newest iPhones, apparently. GL is implemented on top of Metal, which means using OpenGL is only really saving you a bit of development effort – not that much, considering that the promise of “write once, run anywhere” that OpenGL has does not really work out on mobile.
You can verify this yourself by profiling OpenGL ES code on modern iOS versions:
In addition to the above, you'll see Metal-specific operations like -[MTLIOAccelCommandQueue submitCommandBuffers:count:]
appearing in profiling of your OpenGL ES applications.
Near as I can tell, there's no way to circumvent this, it's how rendering is architected on modern iOS versions. That said, I've not seen this alter the behavior of my OpenGL ES code. I have seen different iOS GPUs produce slightly different rendering behavior due to their hardware, so it's possible you're encountering something that is device-specific.
Check for the usual suspects involving precision qualifiers, Z-fighting, division-by-zero in shaders, etc. and see if one of those is messing up your rendering. Those are all places where I've seen new device generations disrupt my rendering.