0

The app uses OpenGL ES2 and the GLKit framework, and the render/update loop provided by GLKitViewController. It used to run at a steady 60 fps on my iPad2 with iOS7.1, but once I updated the iPad2 to iOS8.1, the exact same code now fluctuates between 56-59 FPS. (CPU utlitization, however, remains at 40-60% as before ).

Profiling reveals that the OpenGL drawing commands are using a much larger proportion of CPU time than they used to. The biggest change seems to be that calls to "GLKBaseEffect prepareToDraw" are taking much longer than they used to.

(The app uses a single GLKBaseEffect which is reconfigured at various points during the render loop, neccessitating a call to prepareToDraw each time. I realise it may be possible to optimize by having multiple instances of GLKBaseEffect, and that is something I was considering for later, however, the performance, as it was, was solid on iOS7.1)

I'm now examining the OpenGL ES Analyzer trace in Instruments to determine the OpenGL calls generated by "GLKBaseEffect prepareToDraw", to see if anything seems unusual, and will update the post accordingly once I've managed to figure anything out.

I'd be very grateful for any guidance on how to progress at this point - why might calls to GLKBaseEffect prepareToDraw take longer on iOS8.1?

Amral
  • 1
  • 1
  • If you've found a significant regression then you should log it with Apple (https://bugreport.apple.com) just in case it's a bug. If you can provide example code it would help them. Alternatively, you could use a Technical Support Incident (TSI) and see if an Apple engineer could help you directly. Also, an SO post about slow OpenGL: http://stackoverflow.com/q/22562091/558933 – Robotic Cat Dec 08 '14 at 01:10
  • @RoboticCat Thanks, I will try and do some comparison testing on a iOS7.1 device if I can and then submit a report. The OpenGL Analyzer trace showed nothing unusual - the GL commands generated by prepareToDraw seemed sensible, but I'll re-examine tomorrow morning as quite late here. I wasn't aware of TSI's either, thank you. – Amral Dec 08 '14 at 01:59
  • I can confirm that the GLKBaseEffect prepareToDraw is generating many unnecessary calls to glGetIntegerv(GL_CURRENT_PROGRAM,...) and glGetUniformLocation(). Uniform locations don't change unless a program is re-linked, for example, and I'd expected GLKBaseEffect to cache these locations in CPU-accessed memory. However, I don't know whether the same calls were being generated in iOS7, so this may not be the issue. – Amral Dec 09 '14 at 11:13
  • I found this thread on the Apple forums : "OpenGL Performance Drops > 50% in iOS 8 GM" [link](https://devforums.apple.com/thread/244763?tstart=0) In iOS8, setting a text field in a UIView embedded in the main GLKView was incorrectly causing the superview to layout, which then incorrectly caused the framebuffers to be deallocated/reallocated. I do have a UIView embedded in GLKView, although it's invisible most of the time and only updated once every second rather than once per frame. I'll be able to check later today whether that's the cause of the problem, and will report back. – Amral Dec 09 '14 at 11:18

1 Answers1

0

The cause of the problem was identified by Jim Hillhouse and confirmed by Frogblast on the Apple Dev Forums thread "OpenGL Performance Drops > 50% in iOS 8 GM": setting the text property of a UITextField (or UILabel, in my case) in a view which is a subview of GLKView is causing the GLKView superview to layout, which is then causing framebuffers to be deallocated and reallocated. This wasn't happening in iOS 7.

Jim Hillhouse's workaround was to place the subview inside a UIViewController, and embed that in GLKView. I've done the same, using a Container View to hold the view controller, and can confirm that it works.

Amral
  • 1
  • 1