Question about RLEACCEL-Bug

Hi!

In my game I’m using a ColorKey with activated RLE acceleration
(RLEACCEL). If I now try to access a pixel directly (using the
getpixel()-routine from the docs), I get a segfault. Without the
RLEACCEL-feature the game works as it should.

I am running Linux, the BMP-pics have 24bpp, screen is a 640x480x32
window (pics are converted with SDL_DisplayFormat()).

In the archive of this mailinglist I found similar topics, but no
suggestions/hints for a solution. (If needed I can try to write a short
test-program).

Thanks in advance.

Best regards,

Tim

Tim Sch?rmann wrote:

In my game I’m using a ColorKey with activated RLE acceleration
(RLEACCEL). If I now try to access a pixel directly (using the
getpixel()-routine from the docs), I get a segfault. Without the
RLEACCEL-feature the game works as it should.

http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdllocksurface.html

best regards …
clemens

Hi!

Thanks for the quick answer, but I tried that. :slight_smile: The game segfaults even with the “locked” surface.

Bye,

Tim

Clemens Kirchgatterer schrieb:> > In my game I’m using a ColorKey with activated RLE acceleration

(RLEACCEL). If I now try to access a pixel directly (using the
getpixel()-routine from the docs), I get a segfault. Without the
RLEACCEL-feature the game works as it should.

http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdllocksurface.html

best regards …
clemens


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hello !

In my game I’m using a ColorKey with activated RLE acceleration
(RLEACCEL). If I now try to access a pixel directly (using the
getpixel()-routine from the docs), I get a segfault. Without the
RLEACCEL-feature the game works as it should.

When using RLEACCEL the pixels are
not in their original raw form.
RLEACCEL should be used for sprites
that don’t change their look.

When you need to do pixel operations on
surfaces, don’t use RLEACCEL.

When Locking RLEACCEL Surfaces SDL unpacks the packed
pixelform into a normal surface, attaches that to
the pixel pointer. You then manipulate the pixels
and then call Unlock, then SDL packs this raw pixel form
into the packed RLE form and then SDL deletes the pixels surface.

All these operations combined are VERY expensive.

CU

Hello !

Thanks for the quick answer, but I tried that. :slight_smile: The game segfaults even
with the “locked” surface.

Did you try it the EXACT same way as in the docs ?

void DrawPixel(SDL_Surface *screen, Uint8 R, Uint8 G, Uint8 B)
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);

if ( SDL_MUSTLOCK(screen) ) {
    if ( SDL_LockSurface(screen) < 0 ) {
        return;
    }
}
switch (screen->format->BytesPerPixel) {
    case 1: { /* Assuming 8-bpp */
        Uint8 *bufp;

        bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
        *bufp = color;
    }
    break;

    case 2: { /* Probably 15-bpp or 16-bpp */
        Uint16 *bufp;

        bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
        *bufp = color;
    }
    break;

    case 3: { /* Slow 24-bpp mode, usually not used */
        Uint8 *bufp;

        bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
        *(bufp+screen->format->Rshift/8) = R;
        *(bufp+screen->format->Gshift/8) = G;
        *(bufp+screen->format->Bshift/8) = B;
    }
    break;

    case 4: { /* Probably 32-bpp */
        Uint32 *bufp;

        bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
        *bufp = color;
    }
    break;
}
if ( SDL_MUSTLOCK(screen) ) {
    SDL_UnlockSurface(screen);
}
SDL_UpdateRect(screen, x, y, 1, 1);

}

CU

Hi!

First: A big sorry! It was my fault: I locked the wrong surface… :S

Torsten Giebl schrieb:

When you need to do pixel operations on
surfaces, don’t use RLEACCEL.

In my game, I need the colour-value from several pixels. So I perform only reading-operations. Should I avoid
RLEACCEL in this case too? (The game reacts now as it should :)).

Bye,

Tim

Hello !

In my game, I need the colour-value from several pixels. So I perform only
reading-operations. Should I avoid
RLEACCEL in this case too? (The game reacts now as it should :)).

You should, as SDL cannot guess if
you want read and/or write, so it always has
to go the full circle. If SDL could somehow detect,
okay he only wants to read, SDL would still need to do
the unpacking every time and after the reading delete the
surface again.

CU

[…]

When you need to do pixel operations on
surfaces, don’t use RLEACCEL.

In my game, I need the colour-value from several pixels. So I
perform only reading-operations. Should I avoid
RLEACCEL in this case too? (The game reacts now as it should :)).

Depends… RLE might speed things up a lot in some cases, and then you
don’t want to disable it, obviously. OTOH, having SDL decode and
re-encode the RLE when locking and unlocking is rather expensive, so
the net result could be slower than not using RLE in the first place.

If you only need to read pixels from the surface, you might get away
with blitting from the surface to a “scratchpad” surface, and read
from there. Even doing that for the full surface should be faster
than lock/unlock with RLE, as you avoid the re-encode step - and if
you can get away with reading only a few small rectangles, it should
be pretty fast.

Another trick is to keep a shadow surface; a plain, non-RLE copy of
the “real”, RLE encoded surface. Use the RLE accelerated surface for
blitting, and the RGB shadow for reading.

If you’re doing pixel accurate collission detection, the standard
solution is pretty much the same as the shadow surface version,
except you use a bit map instead (one bit per pixel), to save some
memory and/or speed things up a little further.

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

.------- http://olofson.net - Games, SDL examples -------.
| http://zeespace.net - 2.5D rendering engine |
| http://audiality.org - Music/audio engine |
| http://eel.olofson.net - Real time scripting |
’-- http://www.reologica.se - Rheology instrumentation --'On Sunday 01 July 2007, Tim Sch?rmann wrote:

Hi!

Thanks for the help and informations!

In fact, I’m doing collision detection, :slight_smile: but due to several reasons I
would
like to avoid a seperate “collision-bitmap”.
Anyway, at the moment blitting in “normal” mode is fast enough (the
framerate
without RLE is identical with the framerate with activated RLE
compression), but
I will keep the shadow-bitmap in mind.

Bye,

Tim

Torsten Giebl schrieb:

reading-operations. Should I avoid
RLEACCEL in this case too? (The game reacts now as it should :)).

You should, as SDL cannot guess if
you want read and/or write, so it always has
to go the full circle.

[…]

David Olofson schrieb:> If you only need to read pixels from the surface, you might get away

with blitting from the surface to a “scratchpad” surface, and read
from there. Even doing that for the full surface should be faster
than lock/unlock with RLE, as you avoid the re-encode step - and if
you can get away with reading only a few small rectangles, it should
be pretty fast.

Another trick is to keep a shadow surface; a plain, non-RLE copy of
the “real”, RLE encoded surface. Use the RLE accelerated surface for
blitting, and the RGB shadow for reading.

If you’re doing pixel accurate collission detection, the standard
solution is pretty much the same as the shadow surface version,
except you use a bit map instead (one bit per pixel), to save some
memory and/or speed things up a little further.