[SDL] Blitting / event handling with multiple threads

Olof Bjarnason olof.bjarnason at gmail.com
Mon Jan 31 07:48:51 PST 2005


Threading is not a magic performance booster unless you have a
multiple processor system (which I doubt your customers/target
audience have). Also, because you must synchronize computations
between e.g. drawing and physics updating, you get a lot of extra
work, only for a gain in the similarity between your program and how
you think of your program (not a bad gain but in this case the
trade-off between engineering effort and model-resemblance is really
not worth it, trust me) not to mention the problem of not being able
to call library functions in threads different from the main thread,
in general.

There is nothing that keeps you from doing several game-object updates
inbetween SDL_Flip's, if that is a limiting factor, or not drawing all
object (for example only drawing the ones that have actually moved!).

Could you describe your game a little more specifically? What are the
rules? Is it scrolling? Etc. etc.

If you have followed the usual tricks-of-the-trade from the SDL-faq
(SDL_DisplayFormat eg.), then continue to read.

My general advice is pick up some algorithms book and/or real time
computer graphics book to get ideas on how to improve performance. An
excellent book on the real time rendering subject is

http://www.realtimerendering.com/
(no pun intended :)

.. which covers a lot and has tons of pointers.

What you could do for starters is run a profiler tool ('man gprof' if
your on *nix or "Profiling/Profiler" in MSVC) and find out what is
taking time.

The questions you should ask yourself is "What is the bottleneck?":
1) graphics rendering (could be further subdivided..)
2) logic/physic of the game
3) something else? (O/S stealing your app's time, event handling, ...)
 
Good luck,

/Olof

On Mon, 31 Jan 2005 15:54:27 +0100, Christian Morgner
<christian.morgner at postamt.cs.uni-dortmund.de> wrote:
> Hi,
> 
> I'm trying to write a clone of an old DOS game in C++, using SDL,
> and I've been working on that for about a year now, having tried
> many different methods of event handling and drawing.
> 
> I first tried a structure where there was only one game loop that
> was drawing the objects, updating them and handling input events.
> Using a double-buffered video mode, the loops/sec of the whole game
> were limited to approximately the refresh rate of my monitor, because
> SDL_Flip waits for the vertical retrace.
> 
> The game got more and more complex (and slow), because there were
> hundreds of objects that had to be updated and blitted, so I tried to use
> multiple threads to speed up the game. Unfortunately, SDL doesn't
> support blitting and event handling in any other thread than the main
> thread, so any speed improvement is lost because event handling and
> drawing are limited by SDL_Flip() again.
> 
> Is there any possibility to call each object's draw() method (where a lot
> of blitting is done) from a separate thread, so that only this particular
> thread has to run at 60-80 loops/sec. and the other ones are only
> limitated by the CPU speed?
> 
> My last try was the following one:
> I created three threads where game objects can register themselves,
> and the thread objects call their draw() / update() / event() method
> asynchronously.
> The drawing thread also calls SDL_Flip() and SDL_Delay(10) to synchronize
> with the vertical refresh, so it is the only one that is slowed down, but the
> SDL docs say that it is not safe to call any library function outside the main
> thread.
> 
> Can anyone give advice please?
> 
> -Christian
> 
> (I included a piece of code from main.cpp to show the use of the different threads).
> -----------------------------------------------------------------------------------------------
> int runEventThread(void *ptr)
> {
>         EventThread *threadObject = (EventThread *)ptr;
> 
>  // EventThread::update() just goes through the list of
>  // registered objects and calls their event() method when
>  // an event occurs.
> 
>         while(!threadObject->quit())
>                 threadObject->update();
> }
> 
> int runDrawThread(void *ptr)
> {
>         DrawThread *threadObject = (DrawThread *)ptr;
> 
>  // DrawThread::update() goes through the list of
>  // registered objects and calls their draw() method.
> 
>         while(!threadObject->quit())
>                 threadObject->update();
> }
> 
> int runUpdateThread(void *ptr)
> {
>         UpdateThread *threadObject = (UpdateThread *)ptr;
> 
>  // UpdateThread::update() goes through the list of
>  // registered objects and calls their update() method.
> 
>         while(!threadObject->quit())
>                 threadObject->update();
> }
> 
> int main(int argc, char *argv[])
> {
>         IO *io = new IO();
>         EventThread *eventThread = new EventThread(io);
>         DrawThread *drawThread = new DrawThread(io);
>         UpdateThread *updateThread = new UpdateThread(io);
> 
>         // create threads for drawing and event handling
>         SDL_Thread *event = SDL_CreateThread(runEventThread, (void *)eventThread);
>         SDL_Thread *draw = SDL_CreateThread(runDrawThread, (void *)drawThread);
>         SDL_Thread *update = SDL_CreateThread(runUpdateThread, (void *)updateThread);
> 
>         Dune *dune = new Dune(io, 0, 0, 0, 640, 480, drawThread, updateThread, eventThread);
> 
>         // the event thread quits when it receives an EVENT_QUIT event
>         SDL_WaitThread(event, NULL);
> 
>         updateThread->stop();
>         drawThread->stop();
>         eventThread->stop();
> 
>         SDL_WaitThread(update, NULL);
>         SDL_WaitThread(draw, NULL);
> 
>         delete(dune);
>         delete(updateThread);
>         delete(drawThread);
>         delete(eventThread);
>         delete(io);
> 
> }
> 
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl
>




More information about the SDL mailing list