1

I am trying to multithread my iOS application to make it more responsive. I Would like one thread to handle all of the OpenGL stuff like rendering and loading buffer objects and textures etc. But I am having difficulties achieving this.

I know that a thread should have it's own context in order to call gl functions without risking undefined behaviour. So in my app, I create a new context in the OpenGL dedicated thread, and then set it to the current context. Then I do all the loading and rendering on that thread.

The thing I am getting confused about is the GLKView context. What do I set that to? Do I set it to the context that I created in my new thread? Or do I need to create another context on the main thread and assign that to it? Then make these two contexts share a sharegroup?

jamesrogers93
  • 335
  • 1
  • 5
  • 15

1 Answers1

0

This should work:

  1. Create your background context using init(api:), or using init(api:shareGroup:) and passing nil to the second argument.
  2. Obtain the shareGroup of the background context you just created.
  3. Create a new context passing the shareGroup of 2) as the second argument of the initializer init(api:shareGroup:).
  4. Use the context from 3) to initialize your GLKView.

Also, remember you can not share Vertex Array Objects between contexts. I once implemented asynchronous background loading using a second context, but had to initialize textures, VBOs and IBOs in the background, then rendez-vouz (synchronize) on the main thread (e.g., using GCD) to assemble the VAOs. A real pain...

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
  • Thanks for your answer! I just followed your steps and still could not get it to work. To clarify, 1) Create the background context on my new thread. 2) On the main thread, get the sharegroup from 1). 3) Create a new context and pass it the sharegroup. 4) Iinit GLKView context with context created in 3). Now, during the initialising stage of the app, I use my gl thread to load the gl stuff. Then on the draw call in the controller, I use the gl thread to draw to screen. Do I need to sync the VAOs with the main thread context, even though I am drawing from my dedicated gl thread? – jamesrogers93 Jul 24 '17 at 11:28
  • I have just read this answer https://stackoverflow.com/a/19874708/6066861 that says GLKit presents the render buffer to screen directly after the draw function completes. Since I move the drawing to my GL specific thread, it could be that the GLKit draw function completes before I have actually drawn anything on the thread. Meaning I would have to wait until the thread has completed its task. This defeats the point of doing this on another thread. Perhaps what I was trying to achieve is not feasible with GLKit. – jamesrogers93 Jul 24 '17 at 13:48
  • I see. I haven’t used GLKit (just plain old OpenGL ES), but I always draw on the main thread/context. I used the background context only to preload large resources. – Nicolas Miari Jul 24 '17 at 22:23
  • I haven't tried this, but it should be possible to perform drawing to a texture in the backgroud thread, and then use that (shared) texture on the main context to texture-map (e.g.) a quad, etc... I don't think the final render to screen can be done in anything but the main thread, but I might be wrong... – Nicolas Miari Jul 25 '17 at 01:59
  • 1
    I think i'll use the main thread/context to do the drawing, and the background thread/context to do the preloading. Thanks – jamesrogers93 Jul 25 '17 at 12:47