Event Thread and Another window thread

Say we want to have a main thread (1st) that spawns a 2nd SDL input
thread and a 3rd OpenGL rendering thread.

Is it correct to (theory):

  • Spawn the input thread

  • In input thread do SDL_Init (since I read it’s the main way to get
    input (and video)

  • Poll for events (mutex locks assumed)

  • The rendering thread determines that SDL_init was done

  • It brings up a window

  • It sets up an OpenGL context

  • It draws

  • It waits for events from the input thread (with mutex locks done properly)

Is it correct? Does it need window creation otherwise? I’m worried
that I should make the window elsewhere. Also I’m worried about event
collection context. Does it have to be done only where SDL init was
done, or can it be “moved around”?

SDL requires that SDL_SetVideoMode and SDL_PumpEvents are called from
the “main” thread, i.e. the one that called main(). This severely
limits such an architecture, particularly because SDL_PollEvent() and
SDL_WaitEvent() both call SDL_PumpEvents().

You can still do your OpenGL in a separate thread, but you need to
setup the context in the main thread and then use the "MakeCurrent"
function from your platform to associate the context with the child
thread. SDL 1.3 may contain a platform independent implementation of
MakeCurrent().

Instead, I would do all the initialisation in the main() thread. Once
the context is created, you can spawn the rendering thread. You can
handle input using a separate thread if you are careful. You would
need to call SDL_PumpEvents regularly from the main() thread, and only
use “safe” functions like SDL_PeepEvents from the child thread. I
would probably just make main() my “event” thread, and use a special
(user) event to signal SwapBuffers().

Overall, I’m not sure you’ll gain much by separating the rendering and
input into two threads, the former is already somewhat asynchronous if
you batch your operations correctly, and the latter is not a taxing
operation. Relative to your program, the user generates events
slightly faster than your average glacier moves.

Usually, there are bigger operations which can be moved to separate
threads which gain more parallelism and don’t suffer the limitations
that the window manager inflicts on SDL (yes, the above API
restrictions are due to OS specific implementation details). SDL is
cross platform so to have your code work when porting you must hit the
lowest common denominator.

– BrianOn 17 January 2011 15:01, Michael Menegakis wrote:

Say we want to have a main thread (1st) that spawns a 2nd SDL input
thread and a 3rd ?OpenGL rendering thread.

Is it correct to (theory):

Ok, Now I’m wondering how exactly is that context switching done. Is
it a SDL_CreateWindow() and a SDL_GL_CreateContext() in the main SDL
thread and then a SDL_GL_MakeCurrent() in the rendering thread and
nothing else?

I also thought of having the main SDL thread and input on another
thread (since they have to be together) though I guess that’s mostly
for ‘fun’ since the “main-main” thread that spawned them won’t have
much to do anyway.On Mon, Jan 17, 2011 at 5:32 PM, Brian Barrett <brian.ripoff at gmail.com> wrote:

SDL requires that SDL_SetVideoMode and SDL_PumpEvents are called from
the “main” thread, i.e. the one that called main(). This severely
limits such an architecture, particularly because SDL_PollEvent() and
SDL_WaitEvent() both call SDL_PumpEvents().

You can still do your OpenGL in a separate thread, but you need to
setup the context in the main thread and then use the "MakeCurrent"
function from your platform to associate the context with the child
thread. SDL 1.3 may contain a platform independent implementation of
MakeCurrent().

Instead, I would do all the initialisation in the main() thread. Once
the context is created, you can spawn the rendering thread. You can
handle input using a separate thread if you are careful. You would
need to call SDL_PumpEvents regularly from the main() thread, and only
use “safe” functions like SDL_PeepEvents from the child thread. I
would probably just make main() my “event” thread, and use a special
(user) event to signal SwapBuffers().

Overall, I’m not sure you’ll gain much by separating the rendering and
input into two threads, the former is already somewhat asynchronous if
you batch your operations correctly, and the latter is not a taxing
operation. Relative to your program, the user generates events
slightly faster than your average glacier moves.

Usually, there are bigger operations which can be moved to separate
threads which gain more parallelism and don’t suffer the limitations
that the window manager inflicts on SDL (yes, the above API
restrictions are due to OS specific implementation details). SDL is
cross platform so to have your code work when porting you must hit the
lowest common denominator.

– Brian

Hi Brian.

I managed to have it by having SDL_CreateWindow [hidden], SDL_GL_CreateContext

and DL_GL_MakeCurrent(windows, NULL); in a SDL-dedicated thread.

and a SDL_CreateWindow (another window, shown), SDL_GL_MakeCurrent in
a rendering thread

but now there doesn’t seem to be input.

If I do pumpevents in the SDL thread and peepevents in the rendering
threads, peepevents only returns one event.On Mon, Jan 17, 2011 at 5:32 PM, Brian Barrett <brian.ripoff at gmail.com> wrote:

SDL requires that SDL_SetVideoMode and SDL_PumpEvents are called from
the “main” thread, i.e. the one that called main(). This severely
limits such an architecture, particularly because SDL_PollEvent() and
SDL_WaitEvent() both call SDL_PumpEvents().

You can still do your OpenGL in a separate thread, but you need to
setup the context in the main thread and then use the "MakeCurrent"
function from your platform to associate the context with the child
thread. SDL 1.3 may contain a platform independent implementation of
MakeCurrent().

Instead, I would do all the initialisation in the main() thread. Once
the context is created, you can spawn the rendering thread. You can
handle input using a separate thread if you are careful. You would
need to call SDL_PumpEvents regularly from the main() thread, and only
use “safe” functions like SDL_PeepEvents from the child thread. I
would probably just make main() my “event” thread, and use a special
(user) event to signal SwapBuffers().

Overall, I’m not sure you’ll gain much by separating the rendering and
input into two threads, the former is already somewhat asynchronous if
you batch your operations correctly, and the latter is not a taxing
operation. Relative to your program, the user generates events
slightly faster than your average glacier moves.

Usually, there are bigger operations which can be moved to separate
threads which gain more parallelism and don’t suffer the limitations
that the window manager inflicts on SDL (yes, the above API
restrictions are due to OS specific implementation details). SDL is
cross platform so to have your code work when porting you must hit the
lowest common denominator.

– Brian

On 17 January 2011 15:01, Michael Menegakis <@Michael_Menegakis> wrote:

Say we want to have a main thread (1st) that spawns a 2nd SDL input
thread and a 3rd ?OpenGL rendering thread.

Is it correct to (theory):


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org