6

In my OpenGL-ES 1.1 based app, I'm using CALayers as a source for OpenGL textures. Those CALayers comprise of CGImages and text rendered through CoreGraphics. Another OpenGL texture source is a screenshot of a UIView taken using -[CALAyer renderInContext:] and UIGraphicsGetImageFromCurrentImageContext. Currently, I'm running completely on the main thread.

The latter case in particular is pretty bad because it halts the OpenGL rendering for the whole time it takes to create the UIView and its screenshot.

Now I'm considering to move the OpenGL code into a separate thread hoping to get around this blocking. Ideally, the screenshot would be taken on a different thread (main thread if needed) than the OpenGL rendering.

I wasn't able to find a complete coverage in the documentation about what requires running on the main thread and what not. I found some comments in the iOS 4 release notes, and some comments in specific UIKit methods but I'm missing the complete picture.

The code runs on iOS 4.x or higher.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Ortwin Gentz
  • 52,648
  • 24
  • 135
  • 213

2 Answers2

3

You can do drawing with OpenGL ES on a background thread, as long as you do don't try to access the OpenGL context from another thread at the same time. See Apple's Technical Q&A QA1612 for a little more on this.

I have run into a number of issues with updating CALayer content from a background thread, so I do any work with layers on the main thread. Core Animation fires off its animations on a background thread, anyway.

I'd never updated anything related to UIKit from a background thread, but some aspects of drawing in UIKit were made threadsafe in 4.0. David Duncan comments here that drawing to a context is now threadsafe.

In your case, I wouldn't see a problem with running the OpenGL ES rendering on a background thread (perhaps using a serial dispatch queue in GCD to prevent access to the context from multiple threads at once) and then doing your image grabs on another.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
2

Core Animation is generally thread safe, but UIKit and OpenGL ES (on iOS, at least) are not thread-safe. UIKit must only be used on the main thread, and OpenGL ES must be consistently used on a single thread (usually the main thread.)

Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • Do you think it would work to move OpenGL into a background thread and keep the rest on the main thread? What about the Core Graphics code that generates some of the textures? Can I move that to the OpenGL thread as well? – Ortwin Gentz Dec 29 '10 at 18:46
  • Pure Core Graphics/Quartz can be used on a worker thread, but cannot always cross thread boundaries safely. Anything that uses UIKit (such as the `UIGraphics...` functions) must still run on the main thread. – Jonathan Grynspan Dec 29 '10 at 18:55
  • OpenGL is threadsafe, you just can't use the same context on multiple threads or share resources between different contexts unless they're in a sharegroup. Check out the documentation for EAGLSharegroup (http://developer.apple.com/library/ios/documentation/OpenGLES/Reference/EAGLSharegroup_ClassRef/). – Tommy Jul 07 '11 at 03:16
  • Yes, but I was being simplistic about it. :) – Jonathan Grynspan Jul 07 '11 at 11:56
  • That's wrong, some part form UIKit are also thread-safe:From the apple doku: For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way. – Pascalius Sep 21 '12 at 08:09
  • @Pascalius: Unless you've memorized which specific parts of UIKit are thread-safe (and you haven't), it's safer to avoid the problem entirely. – Jonathan Grynspan Sep 21 '12 at 12:47
  • @JonathanGrynspan Actually I have, since iOS4 drawing to a graphics context in UIKit is safe. Specifically: The routines used to access and manipulate the graphics context can now correctly handle contexts residing on different threads. String and image drawing is now thread-safe. Using color and font objects in multiple threads is now safe to do. UIGraphicsBeginImageContextWithOptions is as well thread-safe. – Pascalius Sep 21 '12 at 14:31