SDL and Flickering

Hello everybody.

I use the SDL 1.2.4 under Linux with XFree 4.2 (or 4.1)

I would like to know if somebody know how to use correctly the flags SDL_HWSURFACE and SDL_DOUBLEBUF. When I set the video mode with SWSURFACE I have no flickering, but with HWSURFACE and/or DOUBLEBUF the screen flicker. I have tried many combinations but the only which gives a correct result is SWSURFACE. I have also tried different drivers : x11, dga, svgalib. I dont remember if it flicker with fbdev.
In fact with with SWSURFACE the result is pretty correct but it seems that it could be quicker with HWSURFACE.

Maybe this flags don’t work under linux ?

Here is the method used to display the game :

while(1)
{
Prepare the image in a buffer;
Copy it in the screen;
SDL_Flip();
}

Julien

At 02:23 PM 5/16/02 +0200, you wrote:

I would like to know if somebody know how to use correctly the flags
SDL_HWSURFACE and SDL_DOUBLEBUF. When I set the video mode with SWSURFACE
I have no flickering, but with HWSURFACE and/or DOUBLEBUF the screen
flicker. I have tried many combinations but the only which gives a correct
result is SWSURFACE. I have also tried different drivers : x11, dga,
svgalib. I dont remember if it flicker with fbdev.
In fact with with SWSURFACE the result is pretty correct but it seems that
it could be quicker with HWSURFACE.

If you use the X11 driver you cannot have HW surface, nor in windowed nor
in fullscreen modes, you can have HW surfaces in fullscreen with DGA, but
only if you execute the application as root.

When working with SW surfaces you don’t need double buffering, at least on
linux where double buffering is done, as above only in fullscreen DGA root
mode.

Anyway SW surfaces are often quicker on MODERN cpus than HW surfaces that
are really useful only on slow machines (let’s say to simplify <=200mhz) or
with REALLY big displays (800x600x32 bits for instance).

Bye,
Gabry (gabrielegreco at tin.it)

Please note that HWSURFACE don’t use hardware under linux.
Under other system it can work. In fact it depends on your drivers and your
OS.
The results of the combined flags can be very different. Best for win32 is
fullscreen/hardware flags. It should easily double your framerate or more.

Your problem is not the hardware, it is the DOUBLEBUF and your understanding
of what it means.

double buffer means really DOUBLE = 2 buffers. Let me explain it a bit
longer.
Normally you got this.

backbuffer -> screenbuffer

Both, backbuffer1 and surfacebuffer are memory blocks. One of them you has
told the system to
show (thats the surfacebuffer) the other is the one you blit all your gfx in
for you game screen.
When you then call flip(), the pointers to the buffers (should!) get
exchanged. Then the system
use backbuffer as screenbuffer and backbuffer as screenbuffer.

The other way is to copy the backbuffer with a fast surface-to-surface blit
from backbuffer to
screenbuffer. Most people think, this is always slower, but also this
depends on your system.

The reason is, that you can’t know how flip() is coded inside the drivers.
SDL will give the
flip() to the driver or low level system (like opengl or directx) when it is
possible.
Under alot of circumstances, a flip() will don’t do a ptr flip(), it will do
a surface copy.
Then you will be faster by doing it by yourself.

Another problem is, that even when flip() will work, it will perhaps need a
moment. Your
drivers will block the grafik card memory to garantie a flicker free blt.
This can be VERY
bad because it can effect your frame rate. I know systems who lose about 30%
frames when doing
a hardware 2 buffer flip.

The worse thing is, that you will not be able to notice the block in all
cases. Modern drivers
don’t block inside the flip(). The flip() will give you back asap the
flipped pointer, but
inside the card hardware the surface memory is still marked as blocked,
until the drivers
has finished the pointer exchange or buffer copy (remember you are on a
mutitask system).

In the second case, your game will stop then inside the next blit() which
hits a blocked memory
surface.

To avoid this, you use DOUBLEBUF. It looks like this

backbuffer1 -> screenbuffer -> backbuffer2

When you call here a flip() after you has drawn your gfx in backbuffer1, all
is shifted by one.
the ptr of backbuffer1 will be your screen, the screen will be backbuffer2
and backbuffer2 will be
your new backbuffer1, where you draw now your new frame.

Now, remember my text above about blocking gfx card memory. Blocked here
after the flip() are only
the old backbuffer1 and the old screenbuffer. But your 2nd backbuffer was
not touched - means,
this gfx card memory is NOT blocked, whatever now happens inside the drivers
and low level systems
with your other 2 buffers. You can start draw a new frame, even when the
drivers has not finished the
exchange of the 2 other buffers.

As useful this is, there is one problem, and thats what invoke your flicker:
you must update BOTH 2 backbuffers - the flip() will not syncronize the
content of the 2 backbuffers.

in your old loop, you only update the content of 1 buffer - but you must do
it 2 times.
This is also the drawback - your system must do more work. Every piece of
gfx must copied 2 times.

draw_screen
update_backbuffer
flip()
update_backbuffer
flip()

Remember that this is not the way your main loop should really do the work.
Because you do here 2 flip()
in a row. The trick to use DOUBLEBUF is to remember for every part how often
you has it updated to screen after the last flip. If you use 2 backbuffers,
you must update this section 2 times to your backbuffer. If you use 3
backbuffers (yes, thats also possible) you must remember to draw this
section 3 times.

You don’t need to “pre-fill” the backbuffers - means 2 flip() in a row like
in the example.
You must just know WHEN you then draw a new frame and want flip(), to update
for the 2nd buffer
too, what you has done for the other too.

At last, when you think about it, you will see that also DOUBLEBUF speed
will depend on your system.
If your system will do a very fast flip(), the time you waste for drawing
each update 2 times instead
of 1 time will effect your frame rate. Then one backbuffer will be faster.

Well, this stuff here is really pain - as game coder you will curse this
very often. At least when you
has mastered your game, sitting at home and thinking all is done and then
got a call from someone who
told you “well, we tried it out and all was fine, but then we got this
system x with card y and sound
z and our frame rate dropped from 75 to 7.5…” argh.

Michael

PS: sorry for the bad english> ----- Original Message -----

From: sdl-admin@libsdl.org [mailto:sdl-admin at libsdl.org]On Behalf Of Julien
Pauty
Sent: Thursday, May 16, 2002 2:23 PM
To: sdl at libsdl.org
Subject: [SDL] SDL and Flickering

Hello everybody.

I use the SDL 1.2.4 under Linux with XFree 4.2 (or 4.1)

I would like to know if somebody know how to use correctly the flags
SDL_HWSURFACE and SDL_DOUBLEBUF. When I set the video mode with SWSURFACE I
have no flickering, but with HWSURFACE and/or DOUBLEBUF the screen flicker.
I have tried many combinations but the only which gives a correct result is
SWSURFACE. I have also tried different drivers : x11, dga, svgalib. I dont
remember if it flicker with fbdev.
In fact with with SWSURFACE the result is pretty correct but it seems that
it could be quicker with HWSURFACE.

Maybe this flags don’t work under linux ?

Here is the method used to display the game :

while(1)
{
Prepare the image in a buffer;
Copy it in the screen;
SDL_Flip();
}

Julien

You should really add this to the FAQs…

16/05/02 15.58.29, “Michael Toennies” <michael.toennies at nord-com.net> wrote:>Please note that HWSURFACE don’t use hardware under linux.

Under other system it can work. In fact it depends on your drivers and your
OS.
The results of the combined flags can be very different. Best for win32 is
fullscreen/hardware flags. It should easily double your framerate or more.

Your problem is not the hardware, it is the DOUBLEBUF and your understanding
of what it means.

double buffer means really DOUBLE = 2 buffers. Let me explain it a bit
longer.
Normally you got this.

backbuffer -> screenbuffer

Both, backbuffer1 and surfacebuffer are memory blocks. One of them you has
told the system to
show (thats the surfacebuffer) the other is the one you blit all your gfx in
for you game screen.
When you then call flip(), the pointers to the buffers (should!) get
exchanged. Then the system
use backbuffer as screenbuffer and backbuffer as screenbuffer.

The other way is to copy the backbuffer with a fast surface-to-surface blit
from backbuffer to
screenbuffer. Most people think, this is always slower, but also this
depends on your system.

The reason is, that you can’t know how flip() is coded inside the drivers.
SDL will give the
flip() to the driver or low level system (like opengl or directx) when it is
possible.
Under alot of circumstances, a flip() will don’t do a ptr flip(), it will do
a surface copy.
Then you will be faster by doing it by yourself.

Another problem is, that even when flip() will work, it will perhaps need a
moment. Your
drivers will block the grafik card memory to garantie a flicker free blt.
This can be VERY
bad because it can effect your frame rate. I know systems who lose about 30%
frames when doing
a hardware 2 buffer flip.

The worse thing is, that you will not be able to notice the block in all
cases. Modern drivers
don’t block inside the flip(). The flip() will give you back asap the
flipped pointer, but
inside the card hardware the surface memory is still marked as blocked,
until the drivers
has finished the pointer exchange or buffer copy (remember you are on a
mutitask system).

In the second case, your game will stop then inside the next blit() which
hits a blocked memory
surface.

To avoid this, you use DOUBLEBUF. It looks like this

backbuffer1 -> screenbuffer -> backbuffer2

When you call here a flip() after you has drawn your gfx in backbuffer1, all
is shifted by one.
the ptr of backbuffer1 will be your screen, the screen will be backbuffer2
and backbuffer2 will be
your new backbuffer1, where you draw now your new frame.

Now, remember my text above about blocking gfx card memory. Blocked here
after the flip() are only
the old backbuffer1 and the old screenbuffer. But your 2nd backbuffer was
not touched - means,
this gfx card memory is NOT blocked, whatever now happens inside the drivers
and low level systems
with your other 2 buffers. You can start draw a new frame, even when the
drivers has not finished the
exchange of the 2 other buffers.

As useful this is, there is one problem, and thats what invoke your flicker:
you must update BOTH 2 backbuffers - the flip() will not syncronize the
content of the 2 backbuffers.

in your old loop, you only update the content of 1 buffer - but you must do
it 2 times.
This is also the drawback - your system must do more work. Every piece of
gfx must copied 2 times.

draw_screen
update_backbuffer
flip()
update_backbuffer
flip()

Remember that this is not the way your main loop should really do the work.
Because you do here 2 flip()
in a row. The trick to use DOUBLEBUF is to remember for every part how often
you has it updated to screen after the last flip. If you use 2 backbuffers,
you must update this section 2 times to your backbuffer. If you use 3
backbuffers (yes, thats also possible) you must remember to draw this
section 3 times.

You don’t need to “pre-fill” the backbuffers - means 2 flip() in a row like
in the example.
You must just know WHEN you then draw a new frame and want flip(), to update
for the 2nd buffer
too, what you has done for the other too.

At last, when you think about it, you will see that also DOUBLEBUF speed
will depend on your system.
If your system will do a very fast flip(), the time you waste for drawing
each update 2 times instead
of 1 time will effect your frame rate. Then one backbuffer will be faster.

Well, this stuff here is really pain - as game coder you will curse this
very often. At least when you
has mastered your game, sitting at home and thinking all is done and then
got a call from someone who
told you “well, we tried it out and all was fine, but then we got this
system x with card y and sound
z and our frame rate dropped from 75 to 7.5…” argh.

Michael

PS: sorry for the bad english

-----Original Message-----
From: sdl-admin at libsdl.org [mailto:sdl-admin at libsdl.org]On Behalf Of Julien
Pauty
Sent: Thursday, May 16, 2002 2:23 PM
To: sdl at libsdl.org
Subject: [SDL] SDL and Flickering

Hello everybody.

I use the SDL 1.2.4 under Linux with XFree 4.2 (or 4.1)

I would like to know if somebody know how to use correctly the flags
SDL_HWSURFACE and SDL_DOUBLEBUF. When I set the video mode with SWSURFACE I
have no flickering, but with HWSURFACE and/or DOUBLEBUF the screen flicker.
I have tried many combinations but the only which gives a correct result is
SWSURFACE. I have also tried different drivers : x11, dga, svgalib. I dont
remember if it flicker with fbdev.
In fact with with SWSURFACE the result is pretty correct but it seems that
it could be quicker with HWSURFACE.

Maybe this flags don’t work under linux ?

Here is the method used to display the game :

while(1)
{
Prepare the image in a buffer;
Copy it in the screen;
SDL_Flip();
}

Julien


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