Window unresponsive on OSX when rendering from another thread

okonomiyonda wrote on Sunday, December 29, 2013:

I am trying to render from another thread besides the main thread, and I’m getting weird results. If I create the window and render from the main thread, everything works. However, if I create the window and render from one of my workload manager threads, everything renders fine but the window itself looks like its never updated. I get a constant spinning beachball, the window title never shows up, and the x/-/+ window buttons never show up.

I am guaranteeing that the rendering and init only ever takes place on the same worker thread, so I shouldn’t have any threading issues. Like I said, the actual rendering seems to be working fine. It just feels like I’m missing something needed to update the window itself

Setup: 2009 Mac Pro, OSX Mavericks, ATI Radeon HD 4870 512 MB

Sample code (all called from my worker thread)

Init:

glfwSetErrorCallback( GlfwErrorHandler );
if( !glfwInit() )
{
    ASSERT_MSG( 0, "glfwInit failed" );
    return -1;
}
 
m_window = glfwCreateWindow(m_screen_size.x, m_screen_size.y, window_name, NULL, NULL);
if( !m_window )
{
    glfwTerminate( );
    ASSERT_MSG( 0, "glfwTerminate failed" );
    return -1;
}
  
glfwMakeContextCurrent( m_window );
// set a default projection
Reshape( m_screen_size.x, m_screen_size.y );

Render code (all called from the worker thread):

// draw some stuff

// end of frame
glfwSwapBuffers( m_window );
 
/* Poll for and process events */
glfwPollEvents( );

Again, rendering is working so I don’t think its anything above. Maybe something in the window update is expecting OGL to be on the main thread.

okonomiyonda wrote on Sunday, December 29, 2013:

additional note: probably unrelated but I’ll mention it anyway. When building glfw I get some warnings about deprecated functions

warning: ‘CGDisplayIOServicePort’ is deprecated: first deprecated in OS X 10.9

warning: ‘SetFrontProcess’ is deprecated: first deprecated in OS X 10.9

warning: ‘gluPerspective’ is deprecated: first deprecated in OS X 10.9 - “Use GLKMatrix4MakePerspective”

warning: ‘gluLookAt’ is deprecated: first deprecated in OS X 10.9 - “Use GLKMatrix4MakeLookAt”

dougbinks wrote on Sunday, December 29, 2013:

I’m not an expert on OSX, and not a GLFW maintainer, but creating windows from another thread except the main one is usually tricky due to event handling, which seems to be the problem here, since the symptoms you describe are similar to not correctly handling windowing messages.

You may be better off creating the window on the main thread and then using glfwMakeContextCurrent to set the main thread’s context to NULL and then the render thread to the one you’ve created ( also see this thread ). Or just render everything on the main thread and push other work to the other threads, which is what I’d advise.

Hope that helps, if not perhaps someone with a little more internal knowledge of OSX and GLFW can help.

okonomiyonda wrote on Sunday, December 29, 2013:

Thanks Doug! That actually was it. Seems the window needed to be created on the main thread and the event handling needed to be done there as well. Outside of that, rendering works fine running in workloads in my workload manager. I am finally free from the tyranny of the render thread. Thanks!

okonomiyonda wrote on Sunday, December 29, 2013:

RTFM

http://www.glfw.org/docs/latest/group__window.html#ga5c336fddf2cbb5b92f65f10fb6043344

“Note This function may only be called from the main thread.”