GP2X Hw Accelerated Sdl


well clearing the cache DID do it. I cant belive it xD I guess despite the differance in filesize firefox decided to use the cache based purely on the fact it was the same name x_X

my app is actually blowing up when I run it on the gp2x atm, but I think it might be my fault. compiling and linking with my _VERBOSE_ flag defined this time to see if i cant spot wth is going on..
 
incidently, can someone test the lib on fw1.4 etc? I only have one gp2x and its a 2.0 machine - i can confirm this sdl fixed the flickering vsync issue in 2.0 - but is it behaving properly on 1.4 and below?
 
I originally thought start/select had changed too, but it turned out to be a typo on my part >>;;

I do have a question though. I was getting considerable slow down in parts of my game, most noticiable after I added FPS calcuating code. (this has always been the case, not just with latest update). For example, my menu was running at 14fps and lots of other sections were slow too. Now I solved this by getting all the background blits (like for the menu it was just a menu background and a logo image, both fairly big) and instead blitting them to a surface that I had created once at initialisaation then in the loop blitting that one surface instead. Suddenly I get 59fps returned by my counter and as thats the highest i ever get it I guess thats just hitting the vsync cap. Now I really dont think i got ALL that speed just by turning two blits into one >>;;

Surfaces I create myself I make using a my own function, dbxCreateImage() and it creates them using the SDL_HWSURFACE flag - im guessing thats where the speed is coming from and any images that are loaded by SDL_LoadIMG() are software surfaces? because the only conlusion I can come to is my normal blitting isnt using the hardware! the screen IS a SDL_HWSURFACE always though. But I cant think of any other reason that using this blit-all-to-one-image-then-blit-that technique so drastically improves the performance of ALL aspects of my game :/ Is there a limit to the amount of hardware surfaces you can have? is this why SDL_LoadImg() doesnt make them HW by default?
 
M-.-n posted on May 25 2006 at 11:14 AM said:
I don't know about FW1.4 .. but It seems I've lost the L&R shoulder in SDL_JoysticGetButton(). can anyone confirm ?
Just tested it, all the buttons register. I'm not sure why, but the physical buttons don't seem to be mapped according to the code.
The code says that the first four buttons are UP, UP_LEFT, UP_RIGHT, DOWN whereas when reading them with JoystickGetButton() they are in the order UP, UP_LEFT, LEFT, DOWN_LEFT (and continue anti-clockwise). Other buttons appear to be in different places too... Strange.
The order I'm getting is:
Updated - I was compiling against a different version
0 = UP; 1 = UP_LEFT, 2 = LEFT, 3 = DOWN_LEFT
4 = DOWN, 5 = DOWN_RIGHT, 6 = RIGHT, 7 = UP-RIGHT
8 = START, 9 = SELECT, 10 = R_SHOULDER, 11 = L_SHOULDER
12 = A, 13 = B, 14 = Y, 15 = X,
16 = VOL+, 17 = VOL-, 18 = JOY_PUSH

This conforms to GPH's latest SDL version.
Also if you download as of now, I've added the code to switch backlight on/off (you'll also need to get this header file and copy it over to ${GP2XDEV}/include/SDL/ or where ever you keep SDL's includes.
The new function is SDL_SYS_JoystickGp2xSys(joystick0, cmd); where joystick0 is the value returned from SDL_JoystickOpen(0), and cmd is either BACK_LIGHT_ON or BACK_LIGHT_OFF. You must open joystick(0) for this to work, else you'll crash you're program!
The reason it's tied to joystick0 is that it uses /dev/GPIO which joystick(0) also uses. Plus you need to open the joystick to pretty much anything anyway :)
Also you can pass BATT_LED_ON or BATT_LED_OFF to turn the red LED on and off.
And as a real bonus it can change the clock speed too if you pass one of:
FCLK_200, FCLK_166, FCLK_133, FCLK_100, FCLK_78, FCLK_64, or FCLK_DEFAULT

I've been meaning to put these in for ages but kept forgetting, fw2.0's SDL has implemented them so I've used the same function & defines (although they have SDL_SYS_JoystickBackLight() which is exactly the same, I've not used that name as it doesn't make sense if you're not adjusting the backlight.)
 
Last edited by a moderator:
Sephnroth posted on May 25 2006 at 01:20 PM said:
Surfaces I create myself I make using a my own function, dbxCreateImage() and it creates them using the SDL_HWSURFACE flag - im guessing thats where the speed is coming from and any images that are loaded by SDL_LoadIMG() are software surfaces? because the only conlusion I can come to is my normal blitting isnt using the hardware! the screen IS a SDL_HWSURFACE always though. But I cant think of any other reason that using this blit-all-to-one-image-then-blit-that technique so drastically improves the performance of ALL aspects of my game :/ Is there a limit to the amount of hardware surfaces you can have? is this why SDL_LoadImg() doesnt make them HW by default?
SDL_LoadIMG always loads as SWSURFACE. To get a HW one do this:
Code:
img_temp = IMG_Load(filename);
img = SDL_DisplayFormat(img_temp);
SDL_FreeSurface(img_temp);
If you're using images with alpha you'll need SDL_DisplayFormatAlpha()
And yes, there is a memory limit for HWSURFACEs, currently 5MB, although I'm going to add support to allow using any or all of the first 16MB of upper memory too. That'll give us 21MB!
 
Last edited by a moderator:
that explains alot! thanks for the code, i'll implement it as a flag in my image loading function so i only load what i need as hardware

would be awesome if we had a full 21megs of hardware mem availiable so good luck with that :D

edit:

another quick question, is there any way to make sdl (or anything) tell me how much of the hardware image memory is in use and/or free? I could make my routines a bit more flexiable if I had access to that information (automatically set certain sized images as hardware if the memory is free, etc)
 
Sephnroth posted on May 25 2006 at 05:21 PM said:
that explains alot! thanks for the code, i'll implement it as a flag in my image loading function so i only load what i need as hardware

would be awesome if we had a full 21megs of hardware mem availiable so good luck with that :D

edit:

another quick question, is there any way to make sdl (or anything) tell me how much of the hardware image memory is in use and/or free? I could make my routines a bit more flexiable if I had access to that information (automatically set certain sized images as hardware if the memory is free, etc)
I'll add functions for telling you maximum HW memory free and largest HW block free. At the moment the only way to tell if there isn't a big enough block of memory is that the call to allocate HW surfaces will fail.
I'll try to add a function to consolidate free areas of HW surfaces as well.
 
Last edited by a moderator:
GP2X_Future_Coder posted on May 25 2006 at 06:40 PM said:
Is it possible to add a function to mirrior HW surfaces so I do not have to do it with SW surfaces? Thanks.
Just to confirm, you want to be able to blit the surface mirrored either horizontally or vertically (or both) without having to create a second copy?
It shouldn't be too hard to implement vertical mirroring in hardware as the stride for src and dst can be set seperately, however horizontally they are both controlled by the same bit.
You don't need to use SW surfaces though, just create another HW surface and copy the pixels over how you want them.
I'll add functions to do this for you if you want (thinks... I could do it by using the hardware to rotate it 180 degrees and add a flag to the blit routine to do the vertical mirroring.)
Thinking of that method - I'll expose the rotater too, it can only rotate by 90, 180 & 270 though.
In summary: Hopefully vertical mirroring will be just a case of setting a flag, horizontal mirroring and rotations will require creating a second HWSURFACE.
 
Last edited by a moderator:
Great that would be fantastic! I would love to have the functions to do everything you said especially the Horizontal mirroring this would save me so much time. Thanks a million!!!!
 
Hey paeryn,

Trying to optimize my app I noticed the following: using SDL_FillRect to clear the screen seems to have a non blocking mechanism.. i.e it returns before finishing the fill. Because of that, some part of the screen gets cleared *after* I draw the pixels on them.

Here's a little screen shot:

sdl_rect.jpg


If I replace the SDL_Rect by a 'normal' memory fill of screen_->pixels ; everything is fine

Hope this helps,

Marc
 
thats very strange, in my little sdl wrapper the dbxSync() function which updates the screen performs a screen wide fill rect after each flip and i've never encountered that behaviour. TTX also makes heavy use of fill rect for drawing its in game gui so no clue why it would only be doing a partial job for you :x
 
M-.-n posted on May 27 2006 at 11:41 AM said:
Trying to optimize my app I noticed the following: using SDL_FillRect to clear the screen seems to have a non blocking mechanism.. i.e it returns before finishing the fill. Because of that, some part of the screen gets cleared *after* I draw the pixels on them.
Cheers for this. I've added a small function that should wait until the blitter finishes up. Best to use it just before you want to write to the surface that you used FillRect. I'm not making the FillRect wait itself as for most small cases the blitter will more than likely finish before you get around to writing.
Code:
void SDL_GP2X_WaitForBlitter();
Use this link as this has both the latest libSDL.a and updated includes.

Just thought though. I take it you're writing directly to the surface (ie not using blit()) after the FillRect? If so you are locking the surface before you start writing to it yourself aren't you?
/*
* SDL_LockSurface() sets up a surface for directly accessing the pixels.
* Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write
* to and read from 'surface->pixels', using the pixel format stored in
* 'surface->format'. Once you are done accessing the surface, you should
* use SDL_UnlockSurface() to release it.
*/
The function SDL_LockSurface() automatically waits for the blitter to finish before returning for this exact reason.
 
Last edited by a moderator:
paeryn posted on May 27 2006 at 04:35 PM said:
Just thought though. I take it you're writing directly to the surface (ie not using blit()) after the FillRect? If so you are locking the surface before you start writing to it yourself aren't you?

Cheers for the explanations. As far as I know (don't have the code right in front of me now) I do lock the surface but maybe at the wrong time. U see I'm using FillRect solely for the purpose of clearing the screen, then writing the text by accessing the surface's pixel one at a time (actually, I should see if preparing small 8x8 bitmaps & blitting them would not be faster). So what I do is:

Lock
FillRect
Write pixels
Unlock

And according to what you say, it meanzzz I'm indeed not waiting for the blitter to finish. So I'll try the wait for blitter thingggy.

Thanks for the help !!
Marc
 
Last edited by a moderator:
M-.-n posted on May 27 2006 at 04:12 PM said:
Lock
FillRect
Write pixels
Unlock
That's the wrong order! You should only lock the surface immediately before you access the pixels, and unlock it immediately after you finish. Any accessing of surfaces through SDL functions (eg when you Blit or FillRect or any other instances) should be done outside of any surface lock.
This the whole purpose of locking surfaces, to tell SDL to make sure it's finished with them before you modify, and unlocking is to tell SDL that you've finished using the surface and that it's okay for SDL to start using them again.
So you should be doing:

FillRect
Lock
Write pixels
Unlock

Hope that clears things up. The WaitForBlitter() routine is called internally by SDL_LockSurface()

M-.-n posted on May 27 2006 at 04:12 PM said:
Lock
FillRect
Write pixels
Unlock
That's the wrong order! You should only lock the surface immediately before you access the pixels, and unlock it immediately after you finish. Any accessing of surfaces through SDL functions (eg when you Blit or FillRect or any other instances) should be done outside of any surface lock.
This the whole purpose of locking surfaces, to tell SDL to make sure it's finished with them before you modify, and unlocking is to tell SDL that you've finished using the surface and that it's okay for SDL to start using them again.
So you should be doing:

FillRect
Lock
Write pixels
Unlock

Hope that clears things up. The WaitForBlitter() routine is called internally by SDL_LockSurface()
 
Last edited by a moderator:
hi paeryn, i "ported" your driver to HH, it seems to works fine, but in 8bpp the palette seems to be xored...
color white appears black on screen, color black appears white on screen etc...

do you have any clue
 
loki666 posted on May 28 2006 at 06:21 PM said:
hi paeryn, i "ported" your driver to HH, it seems to works fine, but in 8bpp the palette seems to be xored...
color white appears black on screen, color black appears white on screen etc...

do you have any clue
The palette problems were fixed months ago (or so I thought), I'll look at it tomorrow and see what I can find.
 
Last edited by a moderator:
Back
Top