GP2X Hw Accelerated Sdl


telengard posted on Feb 2 2006 at 08:06 AM said:
I have one more issue remaining and it's probably something I'm doing. After I'm done showing a virtual keyboard I fill the entire screen w/ SDL_FillRect and a color of black and use NULL to do the whole screen (I've tried a rect too). It does seem to fill correctly but I still see the remnants of the virtual keyboard and it flickers. I am doing a flip() after this too. I don't see this when using SWSURFACES.
How much of the keyboard is still visible? And where about is it on the screen?
If you're double buffering, are you clearing both buffers? NULL should work fine as it sets the rect to be the size of the surface. If you have the screen double buffered it actually allocates another bitmap right after the first and SDL_Flip() switches between them.

I've edited the first post on this thread so the links point to the latest versions.

Woogal: What sort of problems is Quake having with HWSURFACE? The only difference (I think) that there is between them is that HW surfaces don't support being blitted to from a different bpp (as in it tries, but messes up)
 
Last edited by a moderator:
hey payern, I finally got your HW_ACCEL_SDL libs into GP2niX. The beta-test of GP2niX should be out soon... that is if I can get the linux-live scripts to boot correctly ;)
 
paeryn posted on Feb 6 2006 at 12:36 PM said:
Parkydr posted on Feb 6 2006 at 12:13 PM said:
I've rebuilt Freedroid with ooPo's toolchain. All the sound works and FPS has increased from 7-15 to 35-50
Woo Hoo! I was playing that last night. It'll be easier at those speeds :)

I'm afraid you'll have to wait until I get a chance to upload the file again tonight, the text is updated but the file is missing :(

The main difference is that the images of the droids load quicker. The joystick is more responsive but I've changed the handling anyway - I was only handling the 8 main positions not the combinations e.g. left and up left together.
 
Last edited by a moderator:
chimpoid posted on Feb 4 2006 at 06:31 PM said:
critical posted on Feb 4 2006 at 05:53 PM said:
Hi,

Does anyone have a pre-built version of the HW accelerated sdl libs that I could grab a copy of, please? I'm developing on Windows at the moment, as my Windows HTPC is the fastest box I've got :(

Page 9, second post. There's pre-comiled there I think. If not then page 1. Those are the ones I'm using.

Chimpoid
Thanks, Chimpoid. I got it working really quickly once I'd actually been pointed in the right direction :) Paeryn, this is a fantastic piece of work, thanks for producing it.
 
Last edited by a moderator:
paeryn posted on Feb 5 2006 at 08:07 AM said:
telengard posted on Feb 2 2006 at 08:06 AM said:
I have one more issue remaining and it's probably something I'm doing. After I'm done showing a virtual keyboard I fill the entire screen w/ SDL_FillRect and a color of black and use NULL to do the whole screen (I've tried a rect too). It does seem to fill correctly but I still see the remnants of the virtual keyboard and it flickers. I am doing a flip() after this too. I don't see this when using SWSURFACES.
How much of the keyboard is still visible? And where about is it on the screen?
If you're double buffering, are you clearing both buffers? NULL should work fine as it sets the rect to be the size of the surface. If you have the screen double buffered it actually allocates another bitmap right after the first and SDL_Flip() switches between them.

I've edited the first post on this thread so the links point to the latest versions.

Woogal: What sort of problems is Quake having with HWSURFACE? The only difference (I think) that there is between them is that HW surfaces don't support being blitted to from a different bpp (as in it tries, but messes up)

Hi paeryn,

The part of the keyboard that is still visible is the part that isn't written over by xmess itself. Its on the lower part of the screen, centered. The virtual keyboard that I wrote pops up @ the bottom. There is a black border around the emulator's video screen. The part of the keyboard that overlaps that gets overwritten fine, but the outside border which I try to set to black by the SDL_FillRect call (of the entire screen) mentioned earlier doesn't seem to get rid of the remaining remnants of the keyboard. After all this is done, I do a flip(). Yes, I am doing double buffering. I didn't realize I had to clear both buffers. I thought one was offscreen and I always wrote to that and then it got 'flipped' to the screen. From what you are saying it sounds like it might be a little different. How do you clear both of them. And I'm curious as to why it doesn't happen w/ xmess overwriting. They do not use SDL calls but rather write directly to the surface "video memory". Maybe that's it?

Anyway, thanks for your help. As soon as I can get this cleaned up I plan on doing a release w/ your version of SDL and Apple II and Coco2/3 support. :)

(PS I had a glass of wine tonight [a real rarity for me] so please excuse any mistakes above)

~telengard
 
Last edited by a moderator:
telengard posted on Feb 7 2006 at 01:56 AM said:
The part of the keyboard that is still visible is the part that isn't written over by xmess itself. Its on the lower part of the screen, centered. The virtual keyboard that I wrote pops up @ the bottom. There is a black border around the emulator's video screen. The part of the keyboard that overlaps that gets overwritten fine, but the outside border which I try to set to black by the SDL_FillRect call (of the entire screen) mentioned earlier doesn't seem to get rid of the remaining remnants of the keyboard. After all this is done, I do a flip(). Yes, I am doing double buffering. I didn't realize I had to clear both buffers. I thought one was offscreen and I always wrote to that and then it got 'flipped' to the screen. From what you are saying it sounds like it might be a little different. How do you clear both of them. And I'm curious as to why it doesn't happen w/ xmess overwriting. They do not use SDL calls but rather write directly to the surface "video memory". Maybe that's it?
Think of double buffering as having two surfaces A and B.
At first A will be shown on the screen, and all drawing will be to B.
When SDL_Flip() is called B will be shown on the screen and all drawing will be to A.
On the next SDL_Flip() it'll be back to showing A and drawing to B.
This makes SDL_Flip() fast as it just has to set the HW to display the surface you've just been drawing to, and change surface->pixels to point to the one it was showing. It actually does a bit of housekeeping too, but it means it doesn't have to physically copy the drawing surface to the visible surface.
The down side is that after SDL_Flip() your drawing surface has a copy of the frame before the one you've just told it to display.

You'll need to make sure that the area of the virtual keyboard (or at least the areas outside of xmess' virtual screen) is cleared every frame.
To avoid clearing it for every single frame you could have a bit of code after the Flip()
Code:
if (erase_virt_keyb) {
  SDL_FillRect(screen, virt_keyb_rect, 0);
  erase_virt_keyb--;
}
and when you want to remove the keyboard do
Code:
erase_virt_keyb = 2;
that'd make sure the FillRect only gets called for the two frames needed to remove it.
 
Last edited by a moderator:
paeryn posted on Feb 6 2006 at 10:35 PM said:
telengard posted on Feb 7 2006 at 01:56 AM said:
The part of the keyboard that is still visible is the part that isn't written over by xmess itself. Its on the lower part of the screen, centered. The virtual keyboard that I wrote pops up @ the bottom. There is a black border around the emulator's video screen. The part of the keyboard that overlaps that gets overwritten fine, but the outside border which I try to set to black by the SDL_FillRect call (of the entire screen) mentioned earlier doesn't seem to get rid of the remaining remnants of the keyboard. After all this is done, I do a flip(). Yes, I am doing double buffering. I didn't realize I had to clear both buffers. I thought one was offscreen and I always wrote to that and then it got 'flipped' to the screen. From what you are saying it sounds like it might be a little different. How do you clear both of them. And I'm curious as to why it doesn't happen w/ xmess overwriting. They do not use SDL calls but rather write directly to the surface "video memory". Maybe that's it?
Think of double buffering as having two surfaces A and B.
At first A will be shown on the screen, and all drawing will be to B.
When SDL_Flip() is called B will be shown on the screen and all drawing will be to A.
On the next SDL_Flip() it'll be back to showing A and drawing to B.
This makes SDL_Flip() fast as it just has to set the HW to display the surface you've just been drawing to, and change surface->pixels to point to the one it was showing. It actually does a bit of housekeeping too, but it means it doesn't have to physically copy the drawing surface to the visible surface.
The down side is that after SDL_Flip() your drawing surface has a copy of the frame before the one you've just told it to display.

You'll need to make sure that the area of the virtual keyboard (or at least the areas outside of xmess' virtual screen) is cleared every frame.
To avoid clearing it for every single frame you could have a bit of code after the Flip()
Code:
if (erase_virt_keyb) {
  SDL_FillRect(screen, virt_keyb_rect, 0);
  erase_virt_keyb--;
}
and when you want to remove the keyboard do
Code:
erase_virt_keyb = 2;
that'd make sure the FillRect only gets called for the two frames needed to remove it.

Aha, I am doing the FillRect but not *after* the flip. Thanks a lot for clearing that off. Flipping actually makes more sense to me now. :)

~telengard
 
Last edited by a moderator:
Hi paeryn
I only wanted to say that all my problems with the rightmost column are gone now, tnaks a lot for your libs!
 
Hi paeryn,

I want to thank you for your accelerated libs :)

OpenJazz's speed has increased from 20 FPS to 60-100 FPS :eek:

Fenix is also being optimized with them :)

Thanks again
 
Whheeee.... Don't you love speed increases :)

lemon:
It looks like it was the scaler that was causing it then, the screen was 1/1024th smaller than it should have been so it was picking up the next leftmost pixel of the next line.

Telengard:
The FillRect() needs to be done at the start of frame - as long as you get the new screen->pixels after the Flip() but before FillRect()

New possible features:
I was serching through stuff last night when I found out how to tell which frame we're on when interlaced (neither the DPC nor MLC exposes it, but the SC does), so I might add a function to allow forcing 25/30 fps with tv out to try and avoid interlacing artifacts.
Don't hold hopes out too much, but I might also be able to get filtered scaling, it's only theoretical at the mo and it might not work, but I'm going to have a go now.
 
All that is impressive!

Could you show me some bechmarks so I could compare blitter perfomance to my own software routines?
(I'm evaluating adding support for blitter)

Can hardware blitter do some additional operations like shifting/xor/and/or/masking/expansion?
 
The blitter supports all 256 Direct2D ternary raster ops. You have Source, Destination and Pattern. Pattern is 8x8 pixels only.
ROPs are described here
It can do expansion of 1bpp, although I've not tested it.
 
paeryn posted on Feb 8 2006 at 05:42 PM said:
The blitter supports all 256 Direct2D ternary raster ops. You have Source, Destination and Pattern. Pattern is 8x8 pixels only.
ROPs are described here
It can do expansion of 1bpp, although I've not tested it.

ROP aren't my thing but the fraction control/colorkey and this 1bit expansion will be very usefull. It'd imagine to use blitter to preshift data to be further processed by cpu.
 
Last edited by a moderator:
Fraction control is because the blitter can only read/write 32bit words and the addresses must be on a 4-byte boundry so it needs to know which bit within the word to start from.
The two main ROPs you'll need are:
0xcc - Src Copy (*dst = *src) - basic blit
0xf0 - Pat Copy (*dst = *pat) - useful for filling rectangles of solid colour
You can tell the blitter which row in the pattern to start from, but not which column.
 
paeryn posted on Feb 8 2006 at 07:00 PM said:
Fraction control is because the blitter can only read/write 32bit words and the addresses must be on a 4-byte boundry so it needs to know which bit within the word to start from.

So it basically a shifter - exactly what I'd like to use.

paeryn posted on Feb 8 2006 at 07:00 PM said:
The two main ROPs you'll need are:
0xcc - Src Copy (*dst = *src) - basic blit
0xf0 - Pat Copy (*dst = *pat) - useful for filling rectangles of solid colour

Of course.

paeryn posted on Feb 8 2006 at 07:00 PM said:
You can tell the blitter which row in the pattern to start from, but not which column.

Probably one additional barrel shifter was one too many to include. :)
 
Last edited by a moderator:
Radek posted on Feb 8 2006 at 06:19 PM said:
Probably one additional barrel shifter was one too many to include. :)
Either that, or it's a case of not being mentioned in the docs (which wouldn't surprise me) :)
 
Last edited by a moderator:
Just found a bug in the blitter code that could cause blits to be a pixel or two out horizontally,
Also the scaler wasn't looking too good on TVout, scaling an interlaced buffer doesn't work, I'm reverting TVout support to think it isn't interlaced. This doesn't give a perfect image but it'll have to do for now.
I'll upload it later tonight, I want to add the HW cursor in before I do... But I must eat first :wacko:
 
Hi Paeryn. First of all, thanks a lot for your work!

And now, my small problem. I've recompiled my program using your HW accelerated version of SDL, and if I keep the SDL_SWSURFACE flag in SDL_SetVideoMode everything works fine. But if I use SDL_HWSURFACE|SDL_DOUBLEBUF, bitmaps are not shown on screen. On the other hand, it shows two rectangles drawn using SDL_FillRect. I've read the posts about double buffering and SDL_Flip, and I think my problem is related to it, but I still don't know how to solve it.

The sequence of calls I use to draw every frame is:

Code:
if (SDL_MUSTLOCK(screen))
    if (SDL_LockSurface(screen) < 0)
        return;

// Clear the screen
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));

<here I draw bitmaps using SDL_BlitSurface and two small rectangles using SDL_FillRect>

if (SDL_MUSTLOCK(screen))
    SDL_UnlockSurface(screen);

SDL_Flip(screen);

As I said before, the rectangles are shown, but not the bitmaps. Any idea of what am I doing wrong?
 
Back
Top