Flickering On Screen Areas Where There Is No Blit / Update.


Quiest

I like turtles!
Joined
Sep 2, 2004
Messages
3,411
Age
41
Location
Dteuschland ;)
Hello again.

I'm in the state of rewriting Unicolor, and I finally tested a new version on the GP2X,
just to see that there is a lot flickering going on on the screen parts that get not update / where
no blits happen.
While it looks fine on PC (the image remains as it was blitted before) it switches from
black to the image to black to the image, etc.
I can only guess this has something to do with double buffering?
How can I solve this problem? Just use no double buffering?
I'm in 16bit mode, btw.

Here's my init code for the screen:
CODE
SDL_SetVideoMode( x_res, y_res, bitmode, SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | ( fullscreen ? SDL_FULLSCREEN : 0 ) );
 
I'd expect that if you only drew to the front buffer, and so when the buffers were swapped, you would get a screen of black, and a screen of the proper image.
 
So the buffers get swapped with SDL_Flip() I guess?
Is this something gp2x related, since it looks fine on PC?
 
Quiest said:
So the buffers get swapped with SDL_Flip() I guess?
Is this something gp2x related, since it looks fine on PC?
That's how double-buffering and SDL_Flip works. SDL_Flip is DESIGNED to do that, it's just that on non-double-buffered surfaces, it pretends to be SDL_UpdateRect(The Whole Screen) as a convenience. You may not notice it on PC for a million reasons, starting with the fact that it might just be ignoring the flag anyway (SDL allows it to do that if it wants... asking for a HW surface is the same - there's no guarantee you'll get one, you may just end up with a SW surface without any warning).

Double-buffering works by having TWO surfaces, one of which you draw to and one of which is shown on the screen, and then you SDL_Flip to switch them around (usually during a VSync phase, so that the change isn't seen by the user). This way no updates you do ever appear on the screen until the screen is ready for a "refresh", so you don't get tearing/striping/partial screen updates visible to the user. So you're not supposed to Flip until you've prepared EVERYTHING on the screen for the next frame. If you just flip with every element you draw, it'll keep flicking back and forth like you describe. It sounds like you're only ever drawing on one surface and then SDL_Flip()'ing twice before you carry on drawing again.

There's even triple-buffering, which is double-buffering that you do by blitting to the offscreen area from a buffer that you draw on. It's supposed to increase screen smoothness and make you spend less time waiting for the screen to Flip at the cost of memory.

Don't use SDL_Flip on non-double-buffered surfaces unless you comment that it's just a shortcut for SDL_UpdateRect. Double-buffering needs extra logic, you can't just tag DOUBLEBUF to the flags and have it work with anything. And if you're going to double-buffer, you need to check all your writes to the surface and updaterect/flips to make sure that they appear in the right places (i.e. between complete draws of the screen, not halfway through).
 
Last edited by a moderator:
So, wait a sec.

Shouldn't the SDL_Surface* I get from SDL_SetVideoMode always be the correct surface to draw onto?
Since I guess SDL_Flip just exchanges the surface / buffer that the pointer points to, with another one, again and again...
 
Quiest said:
So, wait a sec.

Shouldn't the SDL_Surface* I get from SDL_SetVideoMode always be the correct surface to draw onto?
Since I guess SDL_Flip just exchanges the surface / buffer that the pointer points to, with another one, again and again...
I get exactly the same problem with Ghostbusters and Invaders GP2X, I guess I am making the same mistake, I had assumed that the pointer from SDL_SetVideoMode would always point to the back buffer???
 
Last edited by a moderator:
Ah good thing I'm not alone on this.
Any solution?
How can I access the correct buffer after each flip?

edit:
Stop, I think I get my problem now.
The way I want to do it just works with a single buffer...
 
Gadget, are you writing to the bitmaps yourself (by gabbing screen->pixels) or are you always using SDL's routines.
If the former then you have to re-get screen->pixels every frame as when you use double buffering SDL changes it on every SDL_Flip().
When you call SDL_Flip() on the gp2x the back buffer doesn't get copied to the front, instead the two bitmaps are swapped so that after the flip the back buffer consists of the frame that had been on the display i.e. the frame before the one you had just been drawing to.
 
Back
Top