SDL seems to run slow... or is it just me?

I’ve been working with SDL for a little while now and it seems that it’s a bit
slow. But then, could it just simply be me?

What’s the best way to optimize the code for an SDL application? For instance,
the main message pump. I’m sure there’s a more efficient way than this:

while(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
something;
if( event.type == SDL_KEYDOWN )
do something;
if( event.type == SDL_KEYUP )
do something else;
}

The video subsystem is something I’ve been wondering about.

I have an application that uses several layers and then blits them together for
the final output. Should I instead use just one layer and draw everyting to it
in order so that I get the layered effect?

Any suggestions would be very much appreciated…

Leeor…

how slow does your app run? (fps)
how many blits do you perform?
witch graphics card+cpu+ram do you have?

you should at least use
while(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
something;
else if( event.type == SDL_KEYDOWN )
do something;
else if( event.type == SDL_KEYUP )
do something else;
}

an event has only one type, so after one is found the additional
checking is useless and just takes performance.

leeor_net wrote:> I’ve been working with SDL for a little while now and it seems that it’s a bit

slow. But then, could it just simply be me?

What’s the best way to optimize the code for an SDL application? For instance,
the main message pump. I’m sure there’s a more efficient way than this:

while(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
something;
if( event.type == SDL_KEYDOWN )
do something;
if( event.type == SDL_KEYUP )
do something else;
}

The video subsystem is something I’ve been wondering about.

I have an application that uses several layers and then blits them together for
the final output. Should I instead use just one layer and draw everyting to it
in order so that I get the layered effect?

Any suggestions would be very much appreciated…

Leeor…


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

The video subsystem is something I’ve been wondering about.

I have an application that uses several layers and then blits them together for
the final output. Should I instead use just one layer and draw everyting to it
in order so that I get the layered effect?

The first thing to do is to convert all your surfaces to the screen
format using SDL_DisplayFormat. Otherwise SDL does the conversion on the
fly and this kills ther performance. Once this is done, you must
optimize your layer algorithm. For example if the first layer is almost
covered by the others then you should try to blit only the visible part
of it. I did this to make an efficient parallax effect with a tiled map.
I can send you some code if you want.

Another point is alpha. If you use alpha, you must know that if your
surfaces are in video memory blitting will be dog slow, because the
blitting is done by the CPU. If you don’t need an alpha channel, and if
your surfaces are in video memory the blitting is done by the GPU and is
very fast.>Any suggestions would be very much appreciated…

Leeor…


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

— Julien Pauty wrote:

Another point is alpha. If you use alpha, you must
know that if your
surfaces are in video memory blitting will be dog
slow, because the
blitting is done by the CPU. If you don’t need an
alpha channel, and if
your surfaces are in video memory the blitting is
done by the GPU and is
very fast.

He meant in system memory, the CPU blits very
expensively, and in video memory, the GPU very
inexpensively.

A tip for composing each layer (that will PROBABLY be
helpful, but depending on your program, might be
irrelevant, you really didn’t provide much
information,) you could use a strategy called “Dirty
Rectangles.”

When you do this, each instance of a sprite copies the
space it is to be drawn to before you draw it, once
all sprites have been drawn, you flip your screen
(assuming you’re double buffering,) and then each
sprite can restore the piece of the screen they
copied.

This can sometimes be much faster than drawing the
underlying surface from scratch each frame! (Even tile
based graphics will use less CPU and GPU to do this,
it does use a little more memory though.)__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

— Julien Pauty wrote:

Another point is alpha. If you use alpha, you must
know that if your
surfaces are in video memory blitting will be dog
slow, because the
blitting is done by the CPU. If you don’t need an
alpha channel, and if
your surfaces are in video memory the blitting is
done by the GPU and is
very fast.

He meant in system memory, the CPU blits very
expensively,

On the contrary, the CPU works very fast in system memory - compared
to the CPU working in VRAM, that is…

and in video memory, the GPU very
inexpensively.

Yeah, except that you can’t rely on the GPU doing anything much at all
when using the SDL 2D API. (Unless you use glSDL, which uses the
OpenGL API, which is more likely to be accelerated on most
platforms.)

Now, if you use alpha blending, you can pretty much forget about
acceleration (only glSDL and DirectFB support that AFAIK) - and
what’s worse, if you do alpha blending with the CPU in VRAM, you’ll
effectively downgrade the CPU to something like a 286, due to the
slow VRAM reads.

In short, if you want the best performance on more than one platform,
there’s no simple answer. Sometimes you should use h/w surfaces for
everything. Sometimes you should definitely not use h/w surfaces
for anything but the display surface. In some cases, a some kind of
hybrid may be faster. (For example, if everything but alpha is
accelerated, your best bet may be to use that, and do s/w alpha in
small areas only.)

A tip for composing each layer (that will PROBABLY be
helpful, but depending on your program, might be
irrelevant, you really didn’t provide much
information,) you could use a strategy called “Dirty
Rectangles.”

When you do this, each instance of a sprite copies the
space it is to be drawn to before you draw it, once
all sprites have been drawn, you flip your screen
(assuming you’re double buffering,) and then each
sprite can restore the piece of the screen they
copied.

I would recommend against copying dirty rectangles, unless rendering
the background is extremely expensive and/or you know that blitting
from the screen is accelerated. (If it isn’t, you’ll be doing CPU
reads from VRAM, which - for the 13,546,572nd time - is insanely slow
on pretty much any computer you can find today.)

Instead, just rerender the dirty areas from the map to remove sprites.

Either way, note that you need to do some extra work to make dirty
rects work properly on page flipping double buffered displays. With
plain dirty rects, moving sprites will leave flickering trails.

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Thursday 08 July 2004 05.43, Donny Viszneki wrote:

— David Olofson wrote:

Yeah, except that you can’t rely on the GPU doing
anything much at all
when using the SDL 2D API. (Unless you use glSDL,
which uses the
OpenGL API, which is more likely to be accelerated
on most
platforms.)

Now, if you use alpha blending, you can pretty much
forget about
acceleration (only glSDL and DirectFB support that
AFAIK) - and
what’s worse, if you do alpha blending with the CPU
in VRAM, you’ll
effectively downgrade the CPU to something like a
286, due to the
slow VRAM reads.

I can’t speak for all platforms, but for instance, on
Windows (which, don’t get me wrong, I despise,) SDL
wraps the DirectX 2D interfaces which take advantage
of most GPUs. I assume this is the same in many other
environments (though not all.) I wish I could take
some time to show some sources, but I don’t, and I
might just as well be the one who’s wrong here.

A tip for composing each layer (that will PROBABLY
be
helpful, but depending on your program, might be
irrelevant, you really didn’t provide much
information,) you could use a strategy called
"Dirty
Rectangles."

When you do this, each instance of a sprite copies
the
space it is to be drawn to before you draw it,
once
all sprites have been drawn, you flip your screen
(assuming you’re double buffering,) and then each
sprite can restore the piece of the screen they
copied.

I would recommend against copying dirty rectangles,
unless rendering
the background is extremely expensive and/or you
know that blitting
from the screen is accelerated. (If it isn’t, you’ll
be doing CPU
reads from VRAM, which - for the 13,546,572nd time -
is insanely slow
on pretty much any computer you can find today.)

Instead, just rerender the dirty areas from the map
to remove sprites.

While it will require less memory to do as you’re
suggesting, in, for instance, a tile-graphic based
background will require MORE blitting than traditional
dirty rectangles. For any graphic the size of a single
tile, except when properly aligned, it will require 4
similar tiles to be blitted over it. Whereas with
traditional dirty rectangles, you will have to blit
one tile-sized area from the background into a
separate memory space, and then once from that memory
space back onto the background. At most, that is 2
"tile-sized" blits.

Either way, note that you need to do some extra work
to make dirty
rects work properly on page flipping double buffered
displays. With
plain dirty rects, moving sprites will leave
flickering trails.

That is very true. I sometimes forget this, since my
earliest graphical game programming experience used a
toolkit whose page flipping automatically copied the
current buffer into the back buffer each page flip
(no, you COULDN’T disable it, it was dumb as hell.)>

//David Olofson - Programmer, Composer, Open Source
Advocate

.- Audiality
-----------------------------------------------.
| Free/Open Source audio engine for games and
multimedia. |
| MIDI, modular synthesis, real time effects,
scripting,… |
`----------------------------------->
http://audiality.org -’
http://olofson.net
http://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

I can’t speak for all platforms, but for instance, on
Windows (which, don’t get me wrong, I despise,) SDL
wraps the DirectX 2D interfaces which take advantage
of most GPUs. I assume this is the same in many other
environments (though not all.) I wish I could take
some time to show some sources, but I don’t, and I
might just as well be the one who’s wrong here.

No SDL backend accelerates alpha blits for now. Hw alpha blit support in SDL isn’t finished (it’s not far from working though, and a simple fix does it, but for now it makes it impossible to have backends hw accelerating alpha blits. That’s probably explains why DirectFB has the code for hw alpha blits, but it’s disabled.).

Stephane

[…]

I can’t speak for all platforms, but for instance, on
Windows (which, don’t get me wrong, I despise,) SDL
wraps the DirectX 2D interfaces which take advantage
of most GPUs. I assume this is the same in many other
environments (though not all.) I wish I could take
some time to show some sources, but I don’t, and I
might just as well be the one who’s wrong here.

Well, Windows seems to be the exception here. On Linux and some other
targets, the only way to get any acceleration at all is to use
OpenGL… Not sure about Mac OS and Mac OSX, but from what I’ve
heard, it has about the same performance issues as Linux.

[…]

While it will require less memory to do as you’re
suggesting, in, for instance, a tile-graphic based
background will require MORE blitting than traditional
dirty rectangles. For any graphic the size of a single
tile, except when properly aligned, it will require 4
similar tiles to be blitted over it. Whereas with
traditional dirty rectangles, you will have to blit
one tile-sized area from the background into a
separate memory space, and then once from that memory
space back onto the background. At most, that is 2
"tile-sized" blits.

SDL_SetClipRect() :slight_smile:

Indeed, you still need to access four source memory areas instead of
one which means the risk of cache misses is slightly bigger if you
have tons of graphics.

Either way, pretty much anything (including streaming from the hard
drive in many cases!) is faster than reading from VRAM with the
CPU… Avoid it at (almost) any cost. Only blit from the display
surface if you know that that particular operation (for some
mysterious reason) actually is accelerated or at least relatively
fast. (CPU access to “VRAM” can be fast on consoles and machines
with integrated graphics, but don’t count on it. On graphics cards
with PCI, AGP and similar, bus master DMA is your only option.)

Either way, note that you need to do some extra work
to make dirty
rects work properly on page flipping double buffered
displays. With
plain dirty rects, moving sprites will leave
flickering trails.

That is very true. I sometimes forget this, since my
earliest graphical game programming experience used a
toolkit whose page flipping automatically copied the
current buffer into the back buffer each page flip
(no, you COULDN’T disable it, it was dumb as hell.)

Would be kinda’ nice if you could find out how it’s done in some
reliable way. As it is, all you can do is to look for SDL_HWSURFACE
and SDL_DOUBLEBUF, and hope that you aren’t on some weird backend
that uses a h/w shadow surface while using the back->front blit
method, or worse, some backend that makes all surfaces look like s/w
surfaces, while still using actual page flipping…

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Friday 09 July 2004 08.04, Donny Viszneki wrote:

Julien Pauty wrote:

The video subsystem is something I’ve been wondering about.

I have an application that uses several layers and then blits them
together for the final output. Should I instead use just one layer and
draw everyting to it in order so that I get the layered effect?

The first thing to do is to convert all your surfaces to the screen
format using SDL_DisplayFormat. Otherwise SDL does the conversion on the
fly and this kills ther performance.

Use the SDL_ANYFORMAT flag. Then SDL is not forced to use the bpp you
ask for, and does not have to convert the bpp on each update.

SDL_SetVideoMode( 800, 600, 32, SDL_HWSURFACE | SDL_ANYFORMAT);

HTH
Leonhard

usually you should convert your bitmaps to the current displayformat

  1. when loading a bitmap
  2. when the bpp changes

sdl_anyformat just sets the initial bpp to any format. you still have to
convert the bitmaps for better performance.

Leonhard Vogt wrote:>

Julien Pauty wrote:

The video subsystem is something I’ve been wondering about.

I have an application that uses several layers and then blits them
together for the final output. Should I instead use just one layer
and draw everyting to it in order so that I get the layered effect?

The first thing to do is to convert all your surfaces to the screen
format using SDL_DisplayFormat. Otherwise SDL does the conversion on
the fly and this kills ther performance.

Use the SDL_ANYFORMAT flag. Then SDL is not forced to use the bpp you
ask for, and does not have to convert the bpp on each update.

SDL_SetVideoMode( 800, 600, 32, SDL_HWSURFACE | SDL_ANYFORMAT);

HTH
Leonhard


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

ax\zOn Mon, 12 Jul 2004 09:35:32 +0200, Florian Hufsky wrote:

subsystem is something I’ve been wondering about.
I have an application that uses several layers and then blits them
together for the final output. Should I instead use just one layer and
draw everyting to it in order so that I get the layered effect?


Using Opera’s revolutionary e-mail client: http://www.opera.com/m2/