Surface Memory Corruption?

I have a piece of code in my game that’s particularly affected by memory
corruption due to its high usage of malloc() and free().

In this code, I use SDL_CreateRGBSurface() to make a backup of a surface
I later rotate (for rotating explosion chunks when a starship blows up).
The starship’s original image is copied onto the surface
SDL_CreateRGBSurface() creates and I then rotate that surface (making
yet another surface that is quickly destroyed) for the rotations. This
works well (I suppose I shouldn’t create/destroy so many surfaces, but
that’s another issue) and I’ve always used:

surface->format->Rmask, etc. for the SDL_CreateRGBSurface(). However,
after I added a piece of code that might be causing invalid writes (I
don’t know, I’m going through it and valgrind didn’t find anything),
using the surface->format doesn’t work, and the backup surface is
completely back, immediately after the SDL_BlitSurface() statement I use
to back it up. SDL_BlitSurface() returns 0 though.

If I use the screen’s format, screen->format, the rotating chunks work
again. However, I never had to do this before.

–== My question ==–
Could invalidate writes cause this? Could they cause a newly created
surface to stay black, even after blitting? I have a surface, that when
I dump it via SDL_SaveBMP() it looks fine, I then immediately create a
new surface with SDL_CreateRGBSurface() and use SDL_BlitSurface() to
copy the image to that new back up that was created via creatergbsurface
… and dump that backup immedately with SDL_SaveBMP() … and it’s
black.

How is this possible? If I have Surface A that dumps correctly w/
SDL_SaveBMP(), and I then make Surface B with SDL_CreateRGBSurface(),
using the format of the surface that dumps correctly … and I dump
that backup, how could it be black? What causes that?

Here’s the code (notice for chunk[0], I use the screen->format, which
works, and the other three chunks I use surface, which used to work,
but no longer does after I added more code in another section today):

SDL_Surface *chunk[4];
SDL_Rect src, dest;
int i, which = -1, j, a;

assert(surface);

SDL_SaveBMP(surface, "surface_before.bmp");

/* construct the four pieces of the surface first */
/* first chunk */
src.x = 0;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[0] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,

screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
assert(chunk[0]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[0], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[0], “chunk0.bmp”);
/* second chunk /
src.x = surface->w / 2;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[1] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[1]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[1], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[1], “chunk1.bmp”);
/
third chunk /
src.x = 0;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[2] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[2]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[2], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[2], “chunk2.bmp”);
/
fourth chunk */
src.x = surface->w / 2;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[3] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[3]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[3], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[3], “chunk3.bmp”);

SDL_SaveBMP(surface, "surface_after.bmp");

Any ideas what could cause the backup to go black? Could that be the
memory corruption?

– chris (@Christopher_Thielen)

Hey Chris,

2 things you may or may not be aware of…

  1. malloc() takes a LONG time (well in video game time it takes a long
    time), so you want to minimize this.

  2. rotating surfaces takes a LONG time also!

heres what i think you should do:

when your program loads up (or a level loads up or whatever), load up your
images and for the ones that rotate, rotate and store them in 8 or 16
different positions (16 is the max any game would really need IMO) so when
you need to draw a rotated picture, find the closest match to your rotated
angle and draw that surface.

You should see quite a bit of speed improvement.

For your mem corruption problem i say why debug code you are just going to
eventualy change anyways? Id redesign it like above and if i had memory
corruption after that id try to fix it. That way you wont have to do double
the work.

my 2 cents
Atrix> ----- Original Message -----

From: chris@luethy.net (Christopher Thielen)
To:
Sent: Thursday, May 22, 2003 9:33 PM
Subject: [SDL] Surface Memory Corruption?

I have a piece of code in my game that’s particularly affected by memory
corruption due to its high usage of malloc() and free().

In this code, I use SDL_CreateRGBSurface() to make a backup of a surface
I later rotate (for rotating explosion chunks when a starship blows up).
The starship’s original image is copied onto the surface
SDL_CreateRGBSurface() creates and I then rotate that surface (making
yet another surface that is quickly destroyed) for the rotations. This
works well (I suppose I shouldn’t create/destroy so many surfaces, but
that’s another issue) and I’ve always used:

surface->format->Rmask, etc. for the SDL_CreateRGBSurface(). However,
after I added a piece of code that might be causing invalid writes (I
don’t know, I’m going through it and valgrind didn’t find anything),
using the surface->format doesn’t work, and the backup surface is
completely back, immediately after the SDL_BlitSurface() statement I use
to back it up. SDL_BlitSurface() returns 0 though.

If I use the screen’s format, screen->format, the rotating chunks work
again. However, I never had to do this before.

–== My question ==–
Could invalidate writes cause this? Could they cause a newly created
surface to stay black, even after blitting? I have a surface, that when
I dump it via SDL_SaveBMP() it looks fine, I then immediately create a
new surface with SDL_CreateRGBSurface() and use SDL_BlitSurface() to
copy the image to that new back up that was created via creatergbsurface
… and dump that backup immedately with SDL_SaveBMP() … and it’s
black.

How is this possible? If I have Surface A that dumps correctly w/
SDL_SaveBMP(), and I then make Surface B with SDL_CreateRGBSurface(),
using the format of the surface that dumps correctly … and I dump
that backup, how could it be black? What causes that?

Here’s the code (notice for chunk[0], I use the screen->format, which
works, and the other three chunks I use surface, which used to work,
but no longer does after I added more code in another section today):

SDL_Surface *chunk[4];
SDL_Rect src, dest;
int i, which = -1, j, a;

assert(surface);

SDL_SaveBMP(surface, “surface_before.bmp”);

/* construct the four pieces of the surface first /
/
first chunk /
src.x = 0;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[0] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
assert(chunk[0]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[0], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[0], “chunk0.bmp”);
/
second chunk /
src.x = surface->w / 2;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[1] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[1]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[1], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[1], “chunk1.bmp”);
/
third chunk /
src.x = 0;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[2] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[2]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[2], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[2], “chunk2.bmp”);
/
fourth chunk */
src.x = surface->w / 2;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[3] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[3]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[3], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[3], “chunk3.bmp”);

SDL_SaveBMP(surface, “surface_after.bmp”);

Any ideas what could cause the backup to go black? Could that be the
memory corruption?

– chris (chris at luethy.net)


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

It’s hard to tell from here… but the only time I had similar problems,
it had to do with the alpha channel of the destination surface. Blit
doesn’t copy alpha, so if you blit something opaque over a blank surface
with transparent alpha everywhere, you don’t get an opaque piece but the
same completely transparent surface.

(Red, 50% opaque) blitted over (White, 100) will give (pink, 100). In
the same way, blitting (Red, 100) over (whatever, 0) will give (red, 0)
so you end up with a “blank” image.

If this is your case, I fixed this by hand implementing a copyPixels()
function which does just that, copies pixels, including alpha values.

Lic. Gabriel Gambetta
ARTech - GeneXus Development Team
ggambett at artech.com.uy> ----- Original Message -----

From: Christopher Thielen [mailto:chris@luethy.net]
Sent: Viernes, 23 de Mayo de 2003 01:34 a.m.
To: sdl at libsdl.org
Subject: [SDL] Surface Memory Corruption?

I have a piece of code in my game that’s particularly affected by memory
corruption due to its high usage of malloc() and free().

In this code, I use SDL_CreateRGBSurface() to make a backup of a surface
I later rotate (for rotating explosion chunks when a starship blows up).
The starship’s original image is copied onto the surface
SDL_CreateRGBSurface() creates and I then rotate that surface (making
yet another surface that is quickly destroyed) for the rotations. This
works well (I suppose I shouldn’t create/destroy so many surfaces, but
that’s another issue) and I’ve always used:

surface->format->Rmask, etc. for the SDL_CreateRGBSurface(). However,
after I added a piece of code that might be causing invalid writes (I
don’t know, I’m going through it and valgrind didn’t find anything),
using the surface->format doesn’t work, and the backup surface is
completely back, immediately after the SDL_BlitSurface() statement I use
to back it up. SDL_BlitSurface() returns 0 though.

If I use the screen’s format, screen->format, the rotating chunks work
again. However, I never had to do this before.

–== My question ==–
Could invalidate writes cause this? Could they cause a newly created
surface to stay black, even after blitting? I have a surface, that when
I dump it via SDL_SaveBMP() it looks fine, I then immediately create a
new surface with SDL_CreateRGBSurface() and use SDL_BlitSurface() to
copy the image to that new back up that was created via creatergbsurface
… and dump that backup immedately with SDL_SaveBMP() … and it’s
black.

How is this possible? If I have Surface A that dumps correctly w/
SDL_SaveBMP(), and I then make Surface B with SDL_CreateRGBSurface(),
using the format of the surface that dumps correctly … and I dump
that backup, how could it be black? What causes that?

Here’s the code (notice for chunk[0], I use the screen->format, which
works, and the other three chunks I use surface, which used to work,
but no longer does after I added more code in another section today):

SDL_Surface *chunk[4];
SDL_Rect src, dest;
int i, which = -1, j, a;

assert(surface);

SDL_SaveBMP(surface, “surface_before.bmp”);

/* construct the four pieces of the surface first /
/
first chunk /
src.x = 0;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[0] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
assert(chunk[0]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[0], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[0], “chunk0.bmp”);
/
second chunk /
src.x = surface->w / 2;
src.y = 0;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[1] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[1]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[1], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[1], “chunk1.bmp”);
/
third chunk /
src.x = 0;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[2] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[2]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[2], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[2], “chunk2.bmp”);
/
fourth chunk */
src.x = surface->w / 2;
src.y = surface->h / 2;
src.w = surface->w / 2;
src.h = surface->h / 2;
chunk[3] = SDL_CreateRGBSurface(SDL_SWSURFACE, src.w, src.h,
surface->format->BitsPerPixel, surface->format->Rmask,
surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
assert(chunk[3]);
dest.x = 0;
dest.y = 0;
dest.w = src.w;
dest.h = src.h;
a = SDL_BlitSurface(surface, &src, chunk[3], &dest);
assert(a == 0);
SDL_SaveBMP(chunk[3], “chunk3.bmp”);

SDL_SaveBMP(surface, “surface_after.bmp”);

Any ideas what could cause the backup to go black? Could that be the
memory corruption?

– chris (chris at luethy.net)


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl