Multi-threaded OpenGL+SDL

Hello!

I’m trying to do a simple heightmap viewer that transparently loads
chunks of potentially visible heightmaps in background (in another
thread). Since my application uses framebuffer objects for vertex and
index buffers, I thought it would be logical to convert the heightmap
info those buffers right after loading them in the second thread.
However, my first experience finished with the application crashing as
soon as I call any GL function in the second thread.

Upon closer examination it turned out that I have to make some GL
context active in the second thread, since the context is a
thread-specific variable. I have two choices here: I can make current
the same context I use in main thread, and further use a mutex to avoid
GL reenterancy on the same context, and create a shared GL context and
use it without restrictions, still sharing same FBOs.

However, I found that GL context is burried so deep inside SDL that I
have no access to it. I still was able to do what I need by using
GetCurrentContext() in the main thread, then making a shared context
off it. But that’s quite a hack since it’s a) OpenGL specific, b)
Platform-specific (I use GLX functions here).

In the light of dual-core (and in perspective - quad-core) CPUs
invading the market, threading becomes a imperative for new
applications so that they get the most off the new CPUs. I think SDL
needs some generic solution here.

The sequence when starting a new thread should be this:

  • Unbind current GL context in the original thread.
  • Create a new thread
  • The new thread should create a new shared context using the original
    thread’s context.
  • Make the new context current in the new thread.
  • Signal somehow the original thread that it can make its context
    current again.

I think there should be some special function for starting a new thread
with a GL context in it (SDL_CreateThreadGL ?).

And while I’m at it, I would like to propose one more feature to SDL…
I know it’s not too nice but it would be great if it would be possible
somehow to know SDL window’s handle. I have found no way to find this,
but if this is possible, the following does not matter.

Why I need this is that I use the Ogre 3D engine, and in the new
version native SDL support will be discarded (which is a different long
history) in favour of a generic GLX windowing support (which, of
course, lacks SDL’s window management abilities). So what I would like
is to let SDL create the window, and then pass the display/screen/
window to the GLX driver (it supports this since many applications may
want to embed Ogre rendering windows into them). This also applies to
Windows, not sure about Macs (not sure what kind of window IDs they
have).

So I would propose to add a new function:

int SDL_GetSystemWindow (char *buffer, size_t buffer_size);

which would return the system-specific window ID in a free-form format
(it’s applications responsibility to parse it). For example, on X11
this could be like “display:screen windowid”, on Windows just "HWND"
and so on…
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20070104/7047b3c8/attachment.pgp

Andrew Zabolotny wrote:

Hello!

I’m trying to do a simple heightmap viewer that transparently loads
chunks of potentially visible heightmaps in background (in another
thread). Since my application uses framebuffer objects for vertex and
index buffers, I thought it would be logical to convert the heightmap
info those buffers right after loading them in the second thread.
However, my first experience finished with the application crashing as
soon as I call any GL function in the second thread.

Yes, not all OpenGL implementations are thread-safe. Actually, I know of
no implementation, be it on windows or linux, that is fully thread safe
(by thread safe, I mean doing OpenGL from multiple threads works and
doesn’t cause weird bugs). Nvidia for linux comes close to it, though.

Upon closer examination it turned out that I have to make some GL
context active in the second thread, since the context is a
thread-specific variable. I have two choices here: I can make current
the same context I use in main thread, and further use a mutex to avoid
GL reenterancy on the same context, and create a shared GL context and
use it without restrictions, still sharing same FBOs.

However, I found that GL context is burried so deep inside SDL that I
have no access to it. I still was able to do what I need by using
GetCurrentContext() in the main thread, then making a shared context
off it. But that’s quite a hack since it’s a) OpenGL specific, b)
Platform-specific (I use GLX functions here).

In the light of dual-core (and in perspective - quad-core) CPUs
invading the market, threading becomes a imperative for new
applications so that they get the most off the new CPUs. I think SDL
needs some generic solution here.

Well, SDL doesn’t need a solution. Non thread-safe OpenGL
implementations do.

The sequence when starting a new thread should be this:

  • Unbind current GL context in the original thread.
  • Create a new thread
  • The new thread should create a new shared context using the original
    thread’s context.
  • Make the new context current in the new thread.
  • Signal somehow the original thread that it can make its context
    current again.

I think there should be some special function for starting a new thread
with a GL context in it (SDL_CreateThreadGL ?).

And while I’m at it, I would like to propose one more feature to SDL…
I know it’s not too nice but it would be great if it would be possible
somehow to know SDL window’s handle. I have found no way to find this,
but if this is possible, the following does not matter.

You can do that with SDL_GetWMInfo .

Stephane

Andrew Zabolotny wrote:

From Sat, 06 Jan 2007 20:29:49 +0100
Stephane Marchesin <@Stephane_Marchesin> wrote:

and index buffers, I thought it would be logical to convert the
heightmap info those buffers right after loading them in the second
thread. However, my first experience finished with the application
crashing as soon as I call any GL function in the second thread.

Yes, not all OpenGL implementations are thread-safe. Actually, I know
of no implementation, be it on windows or linux, that is fully thread
safe (by thread safe, I mean doing OpenGL from multiple threads works
and doesn’t cause weird bugs). Nvidia for linux comes close to it,
though.

Well, after reading nvidia’s notes on the driver I’m under the
impression that it supports threading pretty well: most notes
regarding threading is how to fight with various bugs in programs
that don’t use threads properly. And I’m sure this situation will only
improve with time, so it would be good to add at least minimal support
for it in SDL.

Well, from my experience, two threads doing any kind of DMA transfers
to/from the same card (that’s when using two separate contexts) will
result in crashes or weird bugs (screen corruption, card hangup…). So
I really would advise doing that for anything serious. Not to mention
that other OpenGL implementations dont support that kind of things.

Stephane