HOpenGL and --enable-threaded-rts

Glynn Clements glynn.clements@virgin.net
Mon, 17 Jun 2002 15:23:48 +0100

Simon Peyton-Jones wrote:

> This is nasty.  As I understand it, 
> * GLUT assumes that the same OS thread executes some Haskell code,
> calls C, which calls back to Haskell.

All OpenGL calls operate upon the current context and window, which
are per-thread settings. The context is set with glXMakeCurrent (X11)
or wglMakeCurrent (Windows); this sets a specific context and a
specific Drawable (X11) or DC (Windows) as current for the calling

IOW, the OpenGL API isn't so much thread-safe as thread-aware. This is
fine if the program is managing the threads itself, but it's likely to
be a nuisance within a system which switches threads arbitrarily.

GLUT sets the current context/window at appropriate points
(glutCreateWindow, glutSetWindow, and before invoking callbacks). This
works fine providing that the OpenGL calls are made within the thread
in which the callback is invoked.

> * Concurrent Haskell never lets this happen, for very good reason. 
> The thread executing Haskell code is just an anonymous OS thread
> executing multiple Haskell threads.  
> The good reason is this: if one designated OS thread must execute
> a particular bunch of Haskell code, what if that OS thread gets blocked
> doing I/O on behalf of some other Haskell thread?  It's hard to say
> just which Haskell threads "belong" to that designated OS thread.
> The only thing I can think of is that the Haskell call-back thread
> somehow says that it can only be executed by the designated
> OS thread; and when blocks (the Haskell call-back, that is) the
> OS thread doesn't grab another Haskell thread to execute, but
> instead steps aside for an anonymous worker thread to do the job.
> Makes it all more complicated, alas.
> Is there no way to get the "current context" explicitly, and treat
> it as some kind of "handle" that accompanies GLUT calls?

GLUT creates its own contexts, but these aren't available to the
application; at least, not officially; the relevant variables (e.g
__glutCurrentWindow), aren't "static", so you could get them if you
really wanted.

Even so, you would still have to ensure that {glX,wgl}MakeCurrent was
called at the appropriate points. AFAICT, this would require either
interacting directly with the (OS) thread management code, or calling
{glX,wgl}MakeCurrent multiple times before *every* OpenGL call.

Basically, GLUT isn't so much a library as a complete (albeit very
simple) framework. It makes it easy to write simple OpenGL programs,
but it also makes it hard to write real programs.

OTOH, if you don't want to use GLUT, you have to interact with the
native window system, and use the platform-specific "glue" layer
(glX*, wgl* etc) to initialise and manage the rendering "environment"
(although particular toolkits may handle the latter part for you, e.g. 
via an "OpenGL canvas" widget).

Glynn Clements <glynn.clements@virgin.net>