# HG changeset patch # User Ryan C. Gordon # Date 1136479251 0 # Node ID 0aa0000081d583f15578332e32e8cd708cdac48b # Parent cf59e7b91ed41f964ec44350f13e566815b54c41 Added optimized C 32bit RGB<->RGBA alpha masking blitter from Alex Volkov. Fixes Bugzilla #11. diff -r cf59e7b91ed4 -r 0aa0000081d5 src/video/SDL_blit_N.c --- a/src/video/SDL_blit_N.c Thu Jan 05 16:37:46 2006 +0000 +++ b/src/video/SDL_blit_N.c Thu Jan 05 16:40:51 2006 +0000 @@ -1991,6 +1991,52 @@ } } } + +/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */ +static void Blit4to4MaskAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *src = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dst = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + + if (dstfmt->Amask) { + /* RGB->RGBA, SET_ALPHA */ + Uint32 mask = (srcfmt->alpha >> dstfmt->Aloss) << dstfmt->Ashift; + + while ( height-- ) { + DUFFS_LOOP( + { + *dst = *src | mask; + ++dst; + ++src; + }, + width); + src = (Uint32*)((Uint8*)src + srcskip); + dst = (Uint32*)((Uint8*)dst + dstskip); + } + } else { + /* RGBA->RGB, NO_ALPHA */ + Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; + + while ( height-- ) { + DUFFS_LOOP( + { + *dst = *src & mask; + ++dst; + ++src; + }, + width); + src = (Uint32*)((Uint8*)src + srcskip); + dst = (Uint32*)((Uint8*)dst + dstskip); + } + } +} + static void BlitNtoN(SDL_BlitInfo *info) { int width = info->d_width; @@ -2414,8 +2460,18 @@ } sdata->aux_data = table[which].aux_data; blitfun = table[which].blitfunc; - if(a_need == COPY_ALPHA && blitfun == BlitNtoN) - blitfun = BlitNtoNCopyAlpha; + + if(blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */ + /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */ + if ( srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4 && + srcfmt->Rmask == dstfmt->Rmask && + srcfmt->Gmask == dstfmt->Gmask && + srcfmt->Bmask == dstfmt->Bmask ) { + blitfun = Blit4to4MaskAlpha; + } else if ( a_need == COPY_ALPHA ) { + blitfun = BlitNtoNCopyAlpha; + } + } } #ifdef DEBUG_ASM