Crash when unlocking surfaces provided by RotoZoom

I’m using SDL_GFX to rotate sprites, and coming up against an odd bug in its
interaction with SDL1.2.5.

Displaying the rotated sprites works fine, but in order to get a bitmap
collision mask for the rotated sprite, I create a temporary surface with
rotozoom’s rotate function (with smoothing off, to speed it up). I then lock
the surface with SDL_LockSurface( ), read the pixel data to generate the
collision mask, then unlock the surface with SDL_UnlockSurface( ). I’ve used
SDL_MUSTLOCK( ) to check that the surface requires locking, and yes - the
surface needs to be locked.

Unfortunately, when I call SDL_UnlockSurface( ), the program crashes.

If I copy SDL’s 1.2.3 DLL into the directory, not only does the program work
fine, but the surface from rotozoom reports that it does not need to be
locked.

I’ve recompiled SDL_GFX against SDL1.2.5 to make sure that it’s not some
issue with conflicting versions, but the newly compiled version still
doesn’t work with SDL 1.2.5, and still does work with 1.2.3.

Does anyone know of something that has changed in 1.2.5 that might cause
this behaviour?

Keith Lawrence

Hmm, I’ve managed to narrow this down a bit further. It’s a combination of
SDL_GFX, SDL 1.2.5, and glSDL.

glSDL uses SDL_Surface->unused1 to hold a reference to a GL texture. When
the SDL_GFX functions are used to rotate a surface, in SDL 1.2.3 the unused1
field is set to -1. In SDL 1.2.5, it is set to 0. When you try to unlock the
surface, glSDL steps in, unlocks the surface, then checks to see whether
it’s a GL surface which needs sending to the card again. When unused1 is set
to -1, it doesn’t find anything in the texture reference table, realizes
that this is a software surface, and does nothing more. When unused1 is set
to 0, it finds a valid texture in the reference table, thinks the surface is
a GL texture, and tries to send it to the card - this crashes the machine.

SDL_GFX just uses SDL_CreateRGBSurface( ) to get its surfaces, and does not
touch SDL_Surface->unused1 itself - so I’m led to conclude that it’s a
change in SDL. 1.2.3 is returning surfaces with unused1 set to -1, 1.2.5 is
returning surfaces with unused1 set to 0.

Am I right? If so, is there a reason this was changed in 1.2.5? Is SDL
itself at fault, or should glSDL not be relying on unused1?

Keith Lawrence> ----- Original Message -----

From: @Keith_Lawrence (Keith Lawrence)
To:
Sent: Sunday, February 09, 2003 9:47 AM
Subject: [SDL] Crash when unlocking surfaces provided by RotoZoom

I’m using SDL_GFX to rotate sprites, and coming up against an odd bug in
its
interaction with SDL1.2.5.

Displaying the rotated sprites works fine, but in order to get a bitmap
collision mask for the rotated sprite, I create a temporary surface with
rotozoom’s rotate function (with smoothing off, to speed it up). I then
lock
the surface with SDL_LockSurface( ), read the pixel data to generate the
collision mask, then unlock the surface with SDL_UnlockSurface( ). I’ve
used
SDL_MUSTLOCK( ) to check that the surface requires locking, and yes - the
surface needs to be locked.

Unfortunately, when I call SDL_UnlockSurface( ), the program crashes.

If I copy SDL’s 1.2.3 DLL into the directory, not only does the program
work
fine, but the surface from rotozoom reports that it does not need to be
locked.

I’ve recompiled SDL_GFX against SDL1.2.5 to make sure that it’s not some
issue with conflicting versions, but the newly compiled version still
doesn’t work with SDL 1.2.5, and still does work with 1.2.3.

Does anyone know of something that has changed in 1.2.5 that might cause
this behaviour?

Keith Lawrence


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

Hmm, I’ve managed to narrow this down a bit further. It’s a
combination of SDL_GFX, SDL 1.2.5, and glSDL.

Ah, why didn’t you just say you were using glSDL? :slight_smile: It has issues
with this kind of stuff by design, although there’s a patch in recent
SDL versions to deal with it. (It just clears the unused1 field.)
Unfortunately, that doesn’t help when external libs or apps create
SDL_surface structs all on their own…

glSDL uses SDL_Surface->unused1 to hold a reference to a GL
texture. When the SDL_GFX functions are used to rotate a surface,
in SDL 1.2.3 the unused1 field is set to -1.

Hmm… I thought it was unused.

In SDL 1.2.5, it is
set to 0.

Yeah, that’s that new patch. (Previous versions left garbage in that
field.)

[…]

SDL_GFX just uses SDL_CreateRGBSurface( ) to get its surfaces, and
does not touch SDL_Surface->unused1 itself - so I’m led to conclude
that it’s a change in SDL. 1.2.3 is returning surfaces with unused1
set to -1,

Really? I never found any code that touches it at all, and no code to
clear the struct before filling it in. I suppose it might be
something that malloc() does on your platform, becaues I’ve just seen
random garbage in that field.

1.2.5 is returning surfaces with unused1 set to 0.

Am I right? If so, is there a reason this was changed in 1.2.5? Is
SDL itself at fault, or should glSDL not be relying on unused1?

It’s my fault. For some reason I can’t remember, I decided to use
0xffffffff (-1, except this is actually a Uint32!) for “no TexInfo”.
I will change this to 0, so I’ll work cleanly with SDL 1.2.5 and up.
(That’s why the patch is there! It’s just that I didn’t remember that
I used 0xffffffff, rather than 0, so I didn’t fix it when I noticed
the change… heh)

//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`---------------------------> http://olofson.net/audiality -’
http://olofson.nethttp://www.reologica.se —On Sunday 09 February 2003 11.21, Keith Lawrence wrote: