Bug I think

I think I might have found a bug. I have an SDL_Surface that has pixel
data, but after I make a call to SDL_BlitSurface() the pixel data pointer is
NULL. Anyone know why that might happen? Maybe that’s not a bug. Maybe
it’s just shifting it to hardware video and so now requires a lock before
accessing the pixels. However, I later call SDL_SoftStretch() with it and
it crashes internally somewhere, which I assume is because the pixel pointer
is NULL.

Can anyone verify this in the code?

Here’s the context of my situation if it helps:

  • Windows 2000 with desktop bpp of 16.
  • SDL screen created with software surface flag only specified. 16 bit
    surface requested.
  • The bitmap surface this problem is occuring with is 16 bits as well. I
    used SDL_ConvertSurface(). Created with the flags SDL_SRCCOLORKEY |
    SDL_RLEACCEL. After the blit that sets the pixel pointer to NULL the flags
    are SDL_SRCCOLORKEY | SDL_RLEACCEL | SDL_RLEACCELOK.

Need any more info, let me know.

-Jason

perhaps the actual code would help us see what’s happening.On Thursday, March 14, 2002, at 06:01 PM, Jason Hoffoss wrote:

I think I might have found a bug. I have an SDL_Surface that has pixel
data, but after I make a call to SDL_BlitSurface() the pixel data
pointer is
NULL. Anyone know why that might happen? Maybe that’s not a bug.
Maybe
it’s just shifting it to hardware video and so now requires a lock
before
accessing the pixels. However, I later call SDL_SoftStretch() with it
and
it crashes internally somewhere, which I assume is because the pixel
pointer
is NULL.

Can anyone verify this in the code?

Here’s the context of my situation if it helps:

  • Windows 2000 with desktop bpp of 16.
  • SDL screen created with software surface flag only specified. 16 bit
    surface requested.
  • The bitmap surface this problem is occuring with is 16 bits as
    well. I
    used SDL_ConvertSurface(). Created with the flags SDL_SRCCOLORKEY |
    SDL_RLEACCEL. After the blit that sets the pixel pointer to NULL the
    flags
    are SDL_SRCCOLORKEY | SDL_RLEACCEL | SDL_RLEACCELOK.

Need any more info, let me know.

-Jason


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

Jason Hoffoss wrote:

I think I might have found a bug. I have an SDL_Surface that has pixel
data, but after I make a call to SDL_BlitSurface() the pixel data pointer is
NULL. Anyone know why that might happen? Maybe that’s not a bug. Maybe
it’s just shifting it to hardware video and so now requires a lock before
accessing the pixels. However, I later call SDL_SoftStretch() with it and
it crashes internally somewhere, which I assume is because the pixel pointer
is NULL.

  • The bitmap surface this problem is occuring with is 16 bits as well. I
    used SDL_ConvertSurface(). Created with the flags SDL_SRCCOLORKEY |
    SDL_RLEACCEL. After the blit that sets the pixel pointer to NULL the flags
    are SDL_SRCCOLORKEY | SDL_RLEACCEL | SDL_RLEACCELOK.

you must lock surfaces when acessing pixels using RLEACCEL or HWACCEL.
there may be other cases and you should check if your surface needs
locking with SDL_MUSTLOCK(surface).

nowadays SDL also ensures the pixel pointer will be NULL if the surface
must be locked and isn’t.

the SDL stretching isn’t really supported (afaik), it’s probably going
straight for the pixels withouth locking it. just lock it before calling
and you should be set.

note, it’s safe to call the Lock and Unlock, even if the surface doesn’t
need it.

perhaps the actual code would help us see what’s happening.

Ok. Here’s where the pixel pointer becomes NULL:

void Sprite::draw(int x, int y)
{
SDL_Rect rect;

if (!valid)
fatal_error(“Sprite is invalid”);

rect.x = x;
rect.y = y;
SDL_BlitSurface(bitmap, NULL, screen, &rect);
}

That gets called first, and then later this function (in the same object)
gets called:

void Sprite::draw(int x, int y, int w, int h)
{
SDL_Rect rect;

if (!valid)
fatal_error(“Sprite is invalid”);

rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
GDL_stretch_blit(bitmap, NULL, screen, &rect);
}

And here’s GDL_stretch_blit() that was just called:

// A clipping wrapper function for SDL_SoftStretch(), since it just doesn’t
// draw anything at all if any part of src or dest is outside legal limits.
// It also clips to the dest clipping area.
//
// Note: The clipping isn’t perfect, and some distortion occurs due to
// integer rounding off. It’s good enough for my needs, though, not to
// mention I don’t feel like messing around with the math involved with
// this any more than I have already in this function. :slight_smile: If you want to
// try and improve it, then look at xmag and ymag, and do clipping one way
// if it’s >= 1 or do it the other way if it’s < 1. It’s about as hard to
// explain as writing the code would be to do it, but that should point you
// in the right direction.
//
int GDL_stretch_blit(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface
*dest, SDL_Rect *dest_rect)
{
int sx, sy, sw, sh, mw, mh, cx, cy, cw, ch, dif;
int dx, dy, dw, dh, z;
float xmag, ymag;
SDL_Rect src_temp, dest_temp;

/* Make sure the surfaces aren’t locked */
if (!src || !dest) {
SDL_SetError(“GDL_particle_blit: passed a NULL surface”);
return -1;
}

if (src->locked || dest->locked) {
SDL_SetError(“Surfaces must not be locked during blit”);
return -1;
}

if (dest_rect) {
dx = dest_rect->x;
dy = dest_rect->y;
dw = dest_rect->w;
dh = dest_rect->h;

} else {
dx = dy = 0;
dw = dest->w;
dh = dest->h;
dest_rect = &dest_temp;
}

// nothing there…
if ((dw < 1) || (dh < 1))
return 1;

// clip source rectangle to source surface area
if (src_rect) {
sx = src_rect->x;
sy = src_rect->y;
sw = src_rect->w;
sh = src_rect->h;
xmag = float(dw) / float(sw);
ymag = float(dh) / float(sh);

if (sx < 0) {
z = int(sx * xmag);
dx -= z;
dw += z;
sw += sx;
sx = 0;
}

if (sy < 0) {
z = int(sy * ymag);
dy -= z;
dh += z;
sh += sy;
sy = 0;
}

mw = src->w - sx;
mh = src->h - sy;

if (sw >= mw) {
dw -= int((sw - mw) * xmag);
sw = mw;
}

if (sh >= mh) {
dh -= int((sh - mh) * ymag);
sh = mh;
}

} else {
sx = sy = 0;
sw = src->w;
sh = src->h;
xmag = float(dw) / float(sw);
ymag = float(dh) / float(sh);
src_rect = &src_temp;
}

// clip target rectangle to target surface clip rectangle
cx = dest->clip_rect.x;
cy = dest->clip_rect.y;
cw = dest->clip_rect.w;
ch = dest->clip_rect.h;

dif = cx - dx;
if (dif > 0) {
z = int(dif / xmag);
sx += z;
sw -= z;
dx += dif;
dw -= dif;
}

dif = dx + dw - cx - cw;
if (dif > 0) {
sw -= int(dif / xmag);
dw -= dif;
}

dif = cy - dy;
if (dif > 0) {
z = int(dif / ymag);
sy += z;
sh -= z;
dy += dif;
dh -= dif;
}

dif = dy + dh - cy - ch;
if (dif > 0) {
sh -= int(dif / ymag);
dh -= dif;
}

if ((sw < 1) || (sh < 1))
return 1;

src_rect->x = sx;
src_rect->y = sy;
src_rect->w = sw;
src_rect->h = sh;

dest_rect->x = dx;
dest_rect->y = dy;
dest_rect->w = dw;
dest_rect->h = dh;
return SDL_SoftStretch(src, src_rect, dest, dest_rect);
}

-Jason

I think I might have found a bug. I have an SDL_Surface that has pixel
data, but after I make a call to SDL_BlitSurface() the pixel data
pointer is
NULL. Anyone know why that might happen? Maybe that’s not a bug.
Maybe
it’s just shifting it to hardware video and so now requires a lock
before
accessing the pixels. However, I later call SDL_SoftStretch() with it
and
it crashes internally somewhere, which I assume is because the pixel
pointer
is NULL.

Can anyone verify this in the code?

Here’s the context of my situation if it helps:

  • Windows 2000 with desktop bpp of 16.
  • SDL screen created with software surface flag only specified. 16 bit
    surface requested.
  • The bitmap surface this problem is occuring with is 16 bits as
    well. I
    used SDL_ConvertSurface(). Created with the flags SDL_SRCCOLORKEY |
    SDL_RLEACCEL. After the blit that sets the pixel pointer to NULL the
    flags
    are SDL_SRCCOLORKEY | SDL_RLEACCEL | SDL_RLEACCELOK.

Need any more info, let me know.

-Jason


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


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

----- Original Message -----
From: leimbacd@bellsouth.net (David Leimbach)
To:
Sent: Thursday, March 14, 2002 7:18 PM
Subject: Re: [SDL] bug I think

Newsgroups: loki.open-source.sdl

you must lock surfaces when acessing pixels using RLEACCEL or HWACCEL.
there may be other cases and you should check if your surface needs
locking with SDL_MUSTLOCK(surface).

nowadays SDL also ensures the pixel pointer will be NULL if the surface
must be locked and isn’t.

the SDL stretching isn’t really supported (afaik), it’s probably going
straight for the pixels withouth locking it. just lock it before calling
and you should be set.

note, it’s safe to call the Lock and Unlock, even if the surface doesn’t
need it.

Sounds good. One question, though. Suppose SDL_SoftStretch() gets fixed
down the road to do locking properly itself. Will my having locked it cause
problems with it locking it a second time? Or would that just be harmlessly
ignored since it’s already locked?

-Jason

----- Original Message -----
From: pete@visionart.com (Pete J Shinners)
To:
Sent: Thursday, March 14, 2002 9:31 PM
Subject: Re: [SDL] bug I think

Sounds good. One question, though. Suppose SDL_SoftStretch() gets fixed
down the road to do locking properly itself. Will my having locked it cause
problems with it locking it a second time? Or would that just be harmlessly
ignored since it’s already locked?

Locks are recursive, so you’ll be fine.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

Sounds good. One question, though. Suppose SDL_SoftStretch() gets
fixed

down the road to do locking properly itself. Will my having locked it
cause

problems with it locking it a second time? Or would that just be
harmlessly

ignored since it’s already locked?

Locks are recursive, so you’ll be fine.

It’s good that locks can be used recursively of course. But recursive
locking might be very slow on some operating systems. Avoid it if you can is
my advise. :wink:

Dirk Gerrits

I think recursive here referes to the fact that each lock is refcounted.
I would seriously doubt there’s a performance loss involved.On Fri, 2002-03-15 at 14:30, Dirk Gerrits wrote:

Sounds good. One question, though. Suppose SDL_SoftStretch() gets
fixed

down the road to do locking properly itself. Will my having locked it
cause

problems with it locking it a second time? Or would that just be
harmlessly

ignored since it’s already locked?

Locks are recursive, so you’ll be fine.

It’s good that locks can be used recursively of course. But recursive
locking might be very slow on some operating systems. Avoid it if you can is
my advise. :wink:

Dirk Gerrits


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

Jason Hoffoss wrote:

Sounds good. One question, though. Suppose SDL_SoftStretch() gets fixed
down the road to do locking properly itself. Will my having locked it cause
problems with it locking it a second time? Or would that just be harmlessly
ignored since it’s already locked?

it’s fine. fortunately SDL recently moved to a Lock counting mechanism,
so you can safely nest as many Lock/Unlock calls as you desire. i can’t
remember exactly how long ago this was, but before then this sort of
thing was a real problem.