resizing offscreen drawable from 2nd thread

Sage
Posts: 1,232
Joined: 2002.10
Post: #1
<frustrated>
OK I've hit my quota of reboots for the evening, so if anyone has ideas on this, help me out.

(init)
Thread 1:
* create NSWindow
* create NSOpenGLView subclass with context "ctx" and set it as the content view of the window
* setup "ctx", textures etc
* create offscreen NSWindow
* create regular NSView and set it as the content view
* create NSOpenGLContext "offctx" shared with "ctx" and set the view to the NSView
* setup "offctx", more textures
* make "ctx" current and create texture from "offctx" via createTexture: fromView internalFormat:
* init finished, spawn rendering loop on thread 2

(loop)
Thread 1:
* sit and wait for user input

Thread 2:
* render pretty things to "offctx"
* draw "offctx" texture to "ctx" to display result in the onscreen window
* repeat

-- up to this point, everything works. If you're familiar with multithreaded GL you know that getting to this point isn't easy, because resizing the window in Thread 1 while Thread 2 is rendering to "ctx" causes a kernel panic if you don't lock. But, the NSOpenGLView subclass has locks everywhere. I can resize, drag, minimize, toggle fullscreen, everything is OK.

(then... at some later time...)
Thread 1:
* keep waiting for user input

Thread 2:
* due to certain program events, decide to reshape the offscreen drawable to better fit content into the max texture size (i.e. from 512x1024 to 1280x512 or somesuch)
* [offwin setContentSize:thenewsize], this also resizes the content view
* make offctx current --still OK so far
* [offctx update]
KA BOOM, the window server freezes!!

OK, what gives? Except during init, Thread 1 *never* makes "offctx" current, it is only issued commands by Thread 2. The window is offscreen and should never receive any events from Thread 1.

Guh?!
</frustrated>
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
Argh!
"The NSView class is generally thread-safe, with a few exceptions. You should create, destroy, resize, move, and perform other operations on NSView objects only from the main thread of an application."
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Wow, that's a lot more lenient than I was expecting.

My rule of thumb is, don't make calls that touch the UI from a secondary thread.

There's an easy way to get your invocation called from the main thread's event loop, from another thread, if that helps. Otherwise, I suggest PBuffers.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
"UI" is a misnomer here, everything is offscreen. It just happens to be an NSView. I'm using an offscreen window instead of a pbuffer because:
1) it's compatible with Jaguar
2) I don't require mipmaps
3) there's no API to resize a pbuffer after it is created

I tried invoking the drawable resizing bit via performSelectorOnMainThread: but it still hangs the window server. Mad
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
I'm not doing anything as hairy as you're doing, but my game is multithreaded with physics in a separate thread, and with graphics running off a timer ( VBL syncd ) on the main thread.

I've had a lot of situations where something happens in the physics thread that requires changes to be made to the OpenGL state, but obviously I can't just make calls directly. Well, apparently in some cases one can, but I don't feel like KP'ing my machine. So I worked out a queue system where the physics thread can enqueue a request to the drawing thread to perform some sort of action. The drawing thread just processes & flushes the request queue at every loop.

Could something like this help you?

My code is too specific to be generically applicable, but I think the *idea* is valid.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
Did you remember to lock the second thread until the context had been resized?
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #7
@Tomorrow: I can't control the thread that the rendering is done on, because this is a plugin for PCSX and the emulation happens on the second thread as dictated by the app core.

Obviously certain events (window resizing) require synchronization of the two threads; but that is what locks are for.

@OSC: performSelectorOnMainThread:...waitUntilDone:YES should effectively block the second thread until the resize is complete, but the window server still hangs.

I don't get it, why is it acceptable for the window server to freeze? EVER?! Mad

I will look at redoing this with pbuffers.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #8
Well, pbuffers don't work with multisampling in 10.3.7, so forget that. Mad
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #9
Ah, welcome to the wonderful world of Apple OpenGL.

I'd just like to point out, for the record, that Apple's support for threading in OpenGL seems to be better than many other vendors' on other OSes...
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #10
Sure, there are some nice things in Apple's GL-- like having a (mostly) up to date glext.h, some ATI<->nvidia extension cross breeding (APPLE_client_storage, APPLE_texture_range, APPLE_vertex_array_range, ARB_texture_env_crossbar, ATI_texture_env_combine3...), the multi-head/multi-vendor support, and a decent profiler for free.

But the threading drives me crazy. It's the one thing that sends me back ten years, rebooting every few minutes. I feel like I'm programming GS/OS.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #11
Another two dozen reboots later: it looks like adding glFinish() before resizing the offscreen drawable avoids the window server freeze.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #12
arekkusu Wrote:Another two dozen reboots later: it looks like adding glFinish() before resizing the offscreen drawable avoids the window server freeze.

I don't envy you Wink
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Using an offscreen context as a texture Bachus 6 4,857 Aug 10, 2004 09:53 AM
Last Post: Bachus
  OS X glut window resizing bug johnMG 10 4,320 Nov 25, 2003 01:56 PM
Last Post: AnotherJake
  Help with NSOpenGL: Window resizing Tycho 2 3,302 Aug 13, 2003 09:46 PM
Last Post: Tycho