Multiple Threaded Windows
Multiple Threaded Windows
- Subject: Multiple Threaded Windows
- From: Chris Scharver <email@hidden>
- Date: Tue, 7 Oct 2003 13:25:51 -0500
Hello,
Attempting to port a C-based windowing library to MacOS X via Cocoa, I
am having some trouble reconciling the library's existing thread
semantics with AppKit. In particular, the library creates a separate
thread for every window. The library's structure dictates this
behavior. These threads draw into those windows using OpenGL. They also
update events using native OS calls. I'm trying to get a native Cocoa
implementation running, and there are definitely some conflicts. I
think my problems are more specific to AppKit than OpenGL.
After putting Cocoa into thread-safe mode, I am able to create a
windows and its OpenGL contexts from a secondary thread. I have created
my own NSView to process events, so it responds to key presses and
mouse buttons. My main thread does little more than create the
NSApplication, assign its delegate, spawn threads, and start the run
loop. If I stick with one window then things are fine. When I try a
simple examples which creates two windows (each running from their own
thread), I get a kernel panic.
In my PowerBook G4 800's system.log:
Sep 23 12:39:59 vectorsigma mach_kernel: ATIRadeon::submit_buffer:
Overflowed block waiting for FIFO space. Have 4, need 6. RBBM_STATUS
0x80116100
In a dual 1GHz G4 tower with GeForceTi's system.log:
Sep 30 12:53:08 Baltan mach_kernel: IOHIDSystem: postEvent LLEventQueue
overflow.
I use an NSRecursiveLock to make certain that AppKit calls are
serialized, and I also place [NSView lockFocusIfCanDraw] and [NSView
unlockFocus] calls around any drawing code. This is all done
programmatically without nibs. Here is the overall flow:
main
- detach a dummy NSThread to enable better thread safety for Cocoa
- spawn window pthreads, each doing the following:
- create NSWindow
- create custom NSView
- create NSOpenGLContext, attach to NSView
- display the window
- render loop draws into the context
- NSView lockFocusIfCanDraw
- make all OpenGL calls
- NSView unlockFocus
- user events are tracked within main through [NSApp run]
- run loop continues until a quit condition is reached
Is the fact that my code works with a single window just a dangerous
stroke of luck? How does AppKit forward user events from the main
process to objects created in other threads? Each window thread should
run independently. The OpenGL contexts are stored separately on each
thread, so they are not being concurrently accessed. The errors above
indicate that the problem is probably related to blasting too much to
the hardware at one time. Do I need to force serialization of all
OpenGL calls such that no threads are calling OpenGL at the same time?
When I do that, there's no kernel panic. However, that approach creates
a huge performance hit due to the locks, and it also defeats the
purpose of threaded rendering. How do I make multiple threads rendering
to multiple NSOpenGLContexts play nicely while minimizing changes to
the existing library structure?
Because these are NSWindows, could main be colliding with the threads'
calls, thus leading to a situation in which two threads (the render
thread and main) are issuing commands? I don't do any drawing except
from the threads, so each thread is rendering only into its own
context. Something is still corrupting things enough to hang the
hardware. Do I need to do further overloading of NSView to make certain
that the main thread is never trying to do any drawing within the view?
Thanks,
Chris
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.