Slow blitting

I’m new to SDL. I’ve been using OpenGL for my graphics stuff before
hand but felt like using SDL because, well, I’m getting tired of using
OpenGL when I’m not doing 3D stuff. Anyways, right to the point:

I’ve got raw image data that needs to be made into a surface. The image
is RGBA, so I make an unsigned char array of size widthheight4. I’ve
got my handy r/g/b/amask values (courtesy of the SDL doc page) and after
reading in the image data I make the image as follows:

SDL_Surface temp = SDL_CreateRGBSurfaceFrom(gfx_data, tile_width,
tile_height, 32, tile_width
4, rmask, gmask, bmask, amask);
SDL_Surface *srf;

//hasAlpha is set if the image contains any transparency/alpha blending
stuff
if (hasAlpha)
srf = SDL_DisplayFormatAlpha(temp);
else
srf = SDL_DisplayFormat(temp);

Free up the temp image when I’m done, keep srf. So now comes time to
draw. I’m drawing just a single layer tile map, and for my little test
it’s all just the same tile. The draw routine looks like this
(p_offsetx and y are just pixel offsets in the x/y direction to draw the
tile at, for smooth scrolling):

SDL_Rect src, dest;
for (y = max_y_tiles + 1; y >= 0; y–)
{
for (x = 0; x < max_x_tiles + 1; x++)
{
src.x = 0;
src.y = 0;
src.w = tile_width;
src.h = tile_height;
dest.x = x * tile_width - p_offsetx;
dest.y = y * tile_height + p_offsety;

	for (l = 0; l < num_layers; l++)
	{
		//ignore this line, the only line that matters

is the BlitSurface line
//SEE BELOW FOR FURTHER EXPLANATION OF LAST LINE
mn = map[l][y + t_offsety][x + t_offsetx];
if (mn->visible)
SDL_BlitSurface(mn->current_image, &src,
buffer, &dest);
}
}
}

A comment on the SDL_BlitSurface line: for the purposes of this little
test, all the mn->current_image values are just pointing to the same
“srf” surface made previously.

When I scroll around, it looks all chunky, sometimes halts for a second.
After scrolling for maybe like 20 seconds or something then it all
becoems smooth. Weird. It was all smooth when I originally had this
code running in OpenGL using display lists. I’m sure I’m doing
something wrong, like not properly making the image or something like
that. Oh ya, in my main loop I created my SDL window with the flags:

SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN

I’m drawing to the screen surface as made from SDL_SetVideoMode, and at
the end of drawing in the main loop I call SDL_Flip(screen). The way I
understood it, is if I set up SDL_DOUBLEBUFF, that if I drew to my
screen surface, it wasn’t actually immediately drawing to the screen,
and wouldn’t actually display the contents of what I was drawing until
the call to SDL_Flip. Thanks for taking the time to read this. Let me
know if you need me to be more specific on anything.

–jeff w.

Hello Jeff,

JW> //hasAlpha is set if the image contains any transparency/alpha blending
JW> stuff
JW> if (hasAlpha)
JW> srf = SDL_DisplayFormatAlpha(temp);
JW> else
JW> srf = SDL_DisplayFormat(temp);

JW> SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN

Using a hardware surface and alpha blending isn’t a good idea when the
alpha blending is done in software - it means you have to read from
video memory which is slow. If you double buffer and you’re getting a
hardware surface, the buffer is also going to be in video memory.

If you’re going to use alpha, use SDL_SWSURFACE.

I don’t know if that’s the cause of your slowdown though, you’ll have
to give it a go!–
Best regards,
Neil mailto:n.griffiths at virgin.net