GP2X Flip Screens Flickers


GernotFrisch

Member
Joined
Jan 2, 2007
Messages
445
Hi,

when I perform a flipscreen, sometimes it flickers. I think it's showing a memory page somewhere deeper in memory.

Here's my swap-code:
CODE


template<class T> inline void SwapMe(T& a, T& b)
{
register T c;
c=a; a=b; b=c;
}

const unsigned long SCREEN0_HW = 0x3101000; // this is the one to restore afterwards
const unsigned long SCREEN1_HW = 0x3381000; // this is the back buffer when ending

// swap these toghether with pRawFrameBuffer and cBuffer
unsigned long FRONTBUFFER_HW = SCREEN0_HW;
unsigned long BACKBUFFER_HW = SCREEN1_HW;

// dummy blit to force MMSP2's blitter to flush it's cache
void gp2x_dummy_blit(void)
{
// SDL method
do {} while (blitter32[MESGSTATUS] & MESG_BUSY);
blitter32[MESGDSTCTRL] = MESG_DSTENB | MESG_DSTBPP_16;
blitter32[MESGDSTADDR] = 0x3101000;
blitter32[MESGDSTSTRIDE] = 4;
blitter32[MESGSRCCTRL] = MESG_SRCBPP_16 | MESG_INVIDEO;
blitter32[MESGPATCTRL] = MESG_PATENB | MESG_PATBPP_1;
blitter32[MESGFORCOLOR] = ~0;
blitter32[MESGBACKCOLOR] = ~0;
blitter32[MESGSIZE] = (1 << MESG_HEIGHT) | 32;
blitter32[MESGCTRL] = MESG_FFCLR | MESG_XDIR_POS | MESG_YDIR_POS | 0xAA;
asm volatile ("":::"memory");
blitter32[MESGSTATUS] = MESG_BUSY;
do {
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
} while (blitter32[MESGSTATUS] & MESG_BUSY);
}

inline void gp2x_vblank()
{
if (vsync_polarity)
do {} while ( (gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC));
else
do {} while (!(gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC));
}


// Flip the framebuffer pointer
void gp2x_video_flip()
{
// swap pointers
SwapMe(BACKBUFFER_HW, FRONTBUFFER_HW);
SwapMe(Screen.cBuffer, Screen.pRawFrameBuffer);

// VBlank
gp2x_dummy_blit();
gp2x_vblank();

// set still RGB image pointer
// odd part
gp2x_memreg16[MLC_STL_EADRL]=(unsigned short)(FRONTBUFFER_HW & 0xFFFF);
// even part
gp2x_memreg16[MLC_STL_EADRH]=(unsigned short)(FRONTBUFFER_HW >> 16);

// Wait for vblank to end (to prevent 2 close page flips in one frame)
// while (!(data->io[GPIOB_PINLVL] & GPIOB_VSYNC));
}
 
I found the very same problem with the game "UniColor" in the version that got shipped with the F200 CD.
Maybe the coder is here and has already fixed this issue?
 
Shouldn't you be vsyncing _before_ you swap the buffers?

Also I use for vsync - I'm interested to know what the correct method is (if mine isn't right, which it may not be).

CODE
{
// reordered according to latest info in wiki
while ( gp2x_gpio_gets(0x1182) & 0x10);
while (!(gp2x_gpio_gets(0x1182) & 0x10));
}
 
Edited ode for better reading.
Ah. You're waiting for both to complete.
I only swap pointers at first. Swapping the buffers is done with the last 2 lines (no?)
 
Ah, you've edited the first post...
Sorry I didn't understand what you were doing with "SwapMe()"...

And you're doing a dummy blit every vblank... That's something else I don't do (and haven't needed to).

I'd have a look at the paeryn's SDL source code for how he does it - I think he's probably the guy who's looked at this the most..
Ryleh's minimal lib may also be worth a look..
And also (dare I say it) gfoot's Allegro source (can't post without mentioning Allegro at some point :))..
 
kevcal said:
And you're doing a dummy blit every vblank... That's something else I don't do (and haven't needed to).

I've just tried rem'in out this exact same call in my game and it's cleaned up all of the flickering! Cool tip! :)
 
Last edited by a moderator:
You removed the dummy blit at the end?
That might be worth taking a look at.
What code do you use to flip screens then? Can you post it completely?
 
KungPhoo said:
You removed the dummy blit at the end?
That might be worth taking a look at.
What code do you use to flip screens then? Can you post it completely?


The bit that I had some luck with was rem'n out

CODE

//dev note: removes flickering on gp2x. Not issue with pc build?!?
//rem'd...SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255,255,255));

//...call, draw road, draw ai and player.
bool fnRenderCONTROL(Tile *inTiles[], float inFPS)

//...blit the screen
SDL_Flip(screen); //...aka BLIT!



I was drawing a white screen before drawing my actual road.. Removing this code in my case removed the flicking.
 
Last edited by a moderator:
Hi!

The only flicker I noticed some times was caused by the hw enabled sdl libs, as far as I remember things I've read around here.

Other than that I'm practically out of business atm as I cant get my gp2x apps compiled (setting up a working IDE under Vista is some serious shit).

On that sidenote, I've alrady installed VC++ 2005 Express (works fine for my Windows SDL-ing) and followed the tutorial here up to the point with the custom build rules, and stopped right there, as i cant for the heck of me find that in my vc++ express >_< any help?
 
FIXED!

Good Code:
CODE

// gp2x-wiki:
while( gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC ){UNSATURATE}
while(!(gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)){UNSATURATE}



Bad Code:
CODE

if (vsync_polarity)
while ( (gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)) {UNSATURATE}
else
while (!(gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)) {UNSATURATE}
 
KungPhoo said:
FIXED!
Good Code:CODE
// gp2x-wiki:
while( gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC ){UNSATURATE}
while(!(gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)){UNSATURATE}

Bad Code:CODE

if (vsync_polarity)
while ( (gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)) {UNSATURATE}
else
while (!(gp2x_memreg16[GPIOB_PINLVL] & GPIOB_VSYNC)) {UNSATURATE}

Good :)
Out of interest .. what does UNSATURATE do ?
** I do a "sched_yield();" - to give the kernel sound driver a chance..
trouble is writing to SD can still cause sound channel swapping problems :(
and I haven't got the time to root through the kernel source any more.
 
Last edited by a moderator:
kevcal said:
Out of interest .. what does UNSATURATE do ?
Id does asm{nop;} 4 times.
I have no clue why - I've just copy/pasted this from Squidge IIRC.
 
Last edited by a moderator:
Like this?CODE
while (....)
{
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
}
No idea, then - that won't let linux schedule anything else.
Maybe it flushes the instruction cache.. I don't know a thing about ARM processors :)

I'm pretty sure squidge knows what he's doing though :)
Maybe it's something to do with the mmuhack he created?

I've also seen:CODE
asm volatile ("" ::: "memory");
which again I have no idea what it does(!)

EDIT:
Found this comment re the 4xNOPs: "// Throw in some nop's so we don't saturate the address bus with polling requests." ....
 
OK, I finally fixed it for GLBasic.
The problem was, that I was waiting for the blitter to finish, but eventually after that had a few nop;s, which might have led to that flickering. It's gone for good.
 
Back
Top