We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1227 - Regression: SDL_DisplayFormatAlpha() is rather complex (check out code in SDL_compat.c) and not available for 1.3
Summary: Regression: SDL_DisplayFormatAlpha() is rather complex (check out code in SDL...
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: video (show other bugs)
Version: HG 2.0
Hardware: x86 Linux
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-13 07:30 UTC by Jonas Thiem
Modified: 2013-05-21 02:44 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonas Thiem 2011-06-13 07:30:56 UTC
SDL_DisplayFormatAlpha() is rather complex (check out code in SDL_compat.c) and not available for 1.3, which means everyone who wants this functionality with new 1.3 code (not old-style 1.2 code) needs to copy it and adapt it to work with their own target surface (instead of the hacked SDL_PublicSurface dependency of the SDL_compat.c implementation).

As far as I understand it, SDL_ConvertSurface() behaves like SDL_DisplayFormat() and is therefore not a helpful replacement without quite some extra code (which isn't exactly straightforward for beginners).

Suggested implementation based on SDL_DisplayFormatAlpha() (I give up all rights and blah (changes public domain), it is also really just SDL_DisplayFormatAlpha() with 1-2 altered lines):

SDL_Surface* SDL_ConvertSurfaceAlpha(SDL_Surface* src, SDL_PixelFormat* pixel_format, Uint32 flags) {
	SDL_PixelFormat *vf = pixel_format;
    SDL_PixelFormat *format;
    SDL_Surface *converted;
    /* default to ARGB8888 */
    Uint32 amask = 0xff000000;
    Uint32 rmask = 0x00ff0000;
    Uint32 gmask = 0x0000ff00;
    Uint32 bmask = 0x000000ff;

    switch (vf->BytesPerPixel) {
    case 2:
        /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.
           For anything else (like ARGB4444) it doesn't matter
           since we have no special code for it anyway */
        if ((vf->Rmask == 0x1f) &&
            (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {
            rmask = 0xff;
            bmask = 0xff0000;
        }
        break;
	  case 3:
    case 4:
        /* Keep the video format, as long as the high 8 bits are
           unused or alpha */
        if ((vf->Rmask == 0xff) && (vf->Bmask == 0xff0000)) {
            rmask = 0xff;
            bmask = 0xff0000;
        }
        break;

    default:
        /* We have no other optimised formats right now. When/if a new
           optimised alpha format is written, add the converter here */
        break;
    }
    format = SDL_AllocFormat(SDL_MasksToPixelFormatEnum(32, rmask,
                                                            gmask,
                                                            bmask,
                                                            amask));
    if (!format) {
        return NULL;
    }
    converted = SDL_ConvertSurface(src, format, SDL_RLEACCEL);
    SDL_FreeFormat(format);
    return converted;
}

As long as this isn't in SDL, everyone who wishes to do fast SDL_Surface alpha blits who doesn't want to code with the legacy 1.2 API implemented by SDL_compat.c will need to duplicate this porting effort. Therefore I suggest adding this (or something similar, e.g. a flag to SDL_ConvertSurface()) to mainstream.
Comment 1 Sam Lantinga 2013-05-21 02:44:28 UTC
This should be resolved with the new SDL_ConvertSurfaceFormat() API, just specify a format with an alpha channels.

Cheers!