Blitting speeds

> Can somebody please take a look at these blit functions and tell me why they are so slow. I use them in my PowerPak lib, and a tile based display of a 64x64 image at 640x480 is only going at 13fps on a 400mhz AMD K6-2. There have been a few people complain my lib is slow, but how can I possibly speed this up? I know SDL isn't slow because CivCTP is not slow at all, neither are other peoples programs. Should I not use SDL's blit function? > When I use BlitTransparent it slows down to like 4 or 5 fps (2 or 3 if I turn on an alpha value) This doesn't make sense to me. SDL is way fast, and this is just basically a wrapper to SDL. Should I initial SDL/the graphics mode/the surface with a certain flag to speed it up? > Lots of linux news sites are picking up PowerPak and I have been getting hundreds of visitors a week (granted must of the are probably returns) but I would really like to have something a little faster to show them. Karl Bartel pointed out alot of things I was doing that didn't need to be done because SDL does them, but aside from making the user fill in the SDL_Rects themselves I don't think I can do much more. Writing my own blit routine doesn't really make much sense as I am sure Sam has already written a better one than I could anyway. > Thanks for listening to my rambling ignorance and offering any help you can :) I'm kind of new to SDL but did you do a 'DisplayFormat' operation before you do blitting? If the pixel format differs between the two surfaces, SDL will do a conversion while it is blitting.

BTW, where can I find information about PowerPak?–
Thanks,
Prasanth Kumar
@Prasanth_A_Kumar

John Garrison wrote:

I’m kind of new to SDL but did you do a ‘DisplayFormat’ operation
before you
do blitting? If the pixel format differs between the two surfaces,
SDL will
do a conversion while it is blitting.

Well, I when I added this code as well as closed down some apps to
free up memory the framerate jumped from 13 to 24, but no other
programs benefited, could the free memory make a 13-24 difference (I
never tested this program but once so I don’t know how it runs with
full memory available. It doesn’t really make sense that the other
programs didn’t improve any, this should have made a difference
shouldn’t it?

The other thing to consider is whether you are running the best suited
SDL video mode? If not, then every time it is blitted to the screen
would
it need to do the pixel format conversion? They documentation suggest
you
convert the bitmaps (sprites) to match the best video mode and blit
that.–
Prasanth Kumar
@Prasanth_A_Kumar

Prasanth Kumar wrote:

John Garrison wrote:

I’m kind of new to SDL but did you do a ‘DisplayFormat’ operation
before you
do blitting? If the pixel format differs between the two surfaces,
SDL will
do a conversion while it is blitting.

Well, I when I added this code as well as closed down some apps to
free up memory the framerate jumped from 13 to 24, but no other
programs benefited, could the free memory make a 13-24 difference (I
never tested this program but once so I don’t know how it runs with
full memory available. It doesn’t really make sense that the other
programs didn’t improve any, this should have made a difference
shouldn’t it?

The other thing to consider is whether you are running the best suited
SDL video mode? If not, then every time it is blitted to the screen
would
it need to do the pixel format conversion? They documentation suggest
you
convert the bitmaps (sprites) to match the best video mode and blit
that.

I tried playing around with the ‘testsprite’ program which comes with
SDL. I get around 34 fps with 300 sprites and 280 fps with 3 sprites.
There was not a hugh variation regardless of pixel depth or video flags
or even DisplayFormat usage interestingly enough.–
Prasanth Kumar
@Prasanth_A_Kumar

/* Initialize 640x480x16bpp graphics mode */
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWPALETTE|SDL_DOUBLEBUF);

That line should be:

 screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);

You should also use depth 0, and convert your artwork.

Good luck!

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Sam Lantinga wrote:

/* Initialize 640x480x16bpp graphics mode */
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWPALETTE|SDL_DOUBLEBUF);

That line should be:

 screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);

You should also use depth 0, and convert your artwork.

I am still getting 27fps, should I just consider that a hardware limit?
I hope not that would mean my lib will never be useful :frowning:

Check to see if the screen surface is actually giving you double buffering.
If not, the flip call is actually doing a full-screen update, which could
limit your framerate to 20-40 FPS, depending on the speed of your system.

The testsprite program cheats a little by only updating the areas of the
screen that have changed, so it’s fast on both flipping and normal surfaces.

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

Can somebody please take a look at these blit functions and tell me why
they are so slow. I use them in my PowerPak lib, and a tile based display
of a 64x64 image at 640x480 is only going at 13fps on a 400mhz AMD K6-2.
There have been a few people complain my lib is slow, but how can I
possibly speed this up? I know SDL isn’t slow because CivCTP is not slow
at all, neither are other peoples programs. Should I not use SDL’s blit
function?
When I use BlitTransparent it slows down to like 4 or 5 fps (2 or 3 if I
turn on an alpha value) This doesn’t make sense to me. SDL is way fast,
and this is just basically a wrapper to SDL. Should I initial SDL/the
graphics mode/the surface with a certain flag to speed it up?
Lots of linux news sites are picking up PowerPak and I have been getting
hundreds of visitors a week (granted must of the are probably returns) but
I would really like to have something a little faster to show them. Karl
Bartel pointed out alot of things I was doing that didn’t need to be done
because SDL does them, but aside from making the user fill in the
SDL_Rects themselves I don’t think I can do much more. Writing my own blit
routine doesn’t really make much sense as I am sure Sam has already
written a better one than I could anyway.
Thanks for listening to my rambling ignorance and offering any help you
can :slight_smile:

/* Blit from one surface to another */
int PD_Blit (PD_Surface *Src, PD_Surface *Dest, Sint32 SrcX, Sint32 SrcY,
Sint32 DestX, Sint32 DestY, Uint32 W, Uint32 H)
{
SDL_Rect src, dest;

/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;

dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;

SDL_BlitSurface(Src, &src, Dest, &dest);

return 0;
}

/* Blit from one surface to another */
int PD_BlitTransparent (PD_Surface *Src, PD_Surface *Dest, Sint32 SrcX,
Sint32 SrcY, Sint32 DestX, Sint32 DestY, Uint32 W, Uint32 H, PD_Color
Clear, Uint8 Alpha)
{
SDL_Rect src, dest;

/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;

dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;

/* Set the color to be transparent /
SDL_SetColorKey(Src, SDL_SRCCOLORKEY, Clear);
/
Set the alpha value */
SDL_SetAlpha(Src, SDL_SRCALPHA, Alpha);

SDL_BlitSurface(Src, &src, Dest, &dest);

return 0;
}

I’m kind of new to SDL but did you do a ‘DisplayFormat’ operation before
you
do blitting? If the pixel format differs between the two surfaces, SDL
will
do a conversion while it is blitting.

Well, I when I added this code as well as closed down some apps to free up
memory the framerate jumped from 13 to 24, but no other programs
benefited, could the free memory make a 13-24 difference (I never tested
this program but once so I don’t know how it runs with full memory
available. It doesn’t really make sense that the other programs didn’t
improve any, this should have made a difference shouldn’t it?

BTW, where can I find information about PowerPak?

http://www.angelfire.com/va/powerpakgsdk I don’t know how useful it will
be until I find a way to speed up blits. (is it normal for transparent
blitting to be about 1/3 the framerate of regular blitting. I would say
yes as transparency is probably pretty expensive in speed terms.)–
Thanks,
Prasanth Kumar
kumar1@home.com

Prasanth Kumar wrote:

John Garrison wrote:

I’m kind of new to SDL but did you do a ‘DisplayFormat’ operation
before you
do blitting? If the pixel format differs between the two surfaces,
SDL will

The other thing to consider is whether you are running the best suited
SDL video mode? If not, then every time it is blitted to the screen
would
it need to do the pixel format conversion? They documentation suggest
you
convert the bitmaps (sprites) to match the best video mode and blit
that.

Yeah I found that out before I was running in 32bit video and the app
was 16 bit but I switched to 16 bit and it sped up.> –

Prasanth Kumar
kumar1 at home.com

I tried playing around with the ‘testsprite’ program which comes with
SDL. I get around 34 fps with 300 sprites and 280 fps with 3 sprites.
There was not a hugh variation regardless of pixel depth or video flags
or even DisplayFormat usage interestingly enough.

I converted one of my PowerPak examples to pure SDL so the users of this
group might be able to give me better advice. Both the PowerPak and the
SDL versions get 26-27fps. The default setup for the testsprite.c gives
me about 150fps. I have to be doing something wrong. Hopefully you guys
can find it in the following code.

#include <time.h>

#include “SDL/SDL.h”

main(int argc, char *argv[])
{
time_t time1, time2;
int x;
SDL_Surface *screen;
SDL_Rect src;

src.x = 0;
src.y = 230;
src.w = 10;
src.h = 20;

/* Initialize the library */
SDL_Init(SDL_INIT_VIDEO);

/* Initialize 640x480x16bpp graphics mode */
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWPALETTE|SDL_DOUBLEBUF);

/* Start timer */
time(&time1);

/* move the circle across the screen */
for (x = 0; x < 640; x++){
if ( SDL_MUSTLOCK(screen) )
SDL_LockSurface(screen);

  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,

0x00,0x00,0x00));
src.x = x;
SDL_FillRect(screen, &src, SDL_MapRGB(screen->format,
0xff,0x00,0x00));

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

 SDL_Flip(screen);

}

/* Stop Timer */
time(&time2);

fprintf(stderr,“fps = %d\n”, 640/(time2-time1));

/* Cleanup */
SDL_Quit();
}

Sam Lantinga wrote:

/* Initialize 640x480x16bpp graphics mode */
screen = SDL_SetVideoMode(640, 480, 16, SDL_HWPALETTE|SDL_DOUBLEBUF);

That line should be:

 screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);

You should also use depth 0, and convert your artwork.

I am still getting 27fps, should I just consider that a hardware limit?
I hope not that would mean my lib will never be useful :frowning:

Check to see if the screen surface is actually giving you double buffering.
If not, the flip call is actually doing a full-screen update, which could
limit your framerate to 20-40 FPS, depending on the speed of your system.

That was it, I replaced SDL_Flip with SDL_UpdateRects and got the same
framerate. So I only updated the area that needed it with
SDL_UpdateRects and got 160fps. I have been wanting to implement a dirty
rectangles type routine for such an occasion, but that really wouldn’t
help with a tiling engine that retiles the whole screen, I had my own
doublebuffer before I found out about SDL_Flip, but that was the same
slow speed, is there a speedy way to implement a double buffer? (maybe
one of the examples demonstrates this I don’t know)

Anyway thanks for the help at least now I know what direction to go
about fixing it in :)>

The testsprite program cheats a little by only updating the areas of the
screen that have changed, so it’s fast on both flipping and normal surfaces.

    -Sam Lantinga                           (slouken at devolution.com)

Lead Programmer, Loki Entertainment Software

“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec