Added optimized C 32bit RGB<->RGBA alpha masking blitter from Alex Volkov.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 05 Jan 2006 16:40:51 +0000
changeset 12320aa0000081d5
parent 1231 cf59e7b91ed4
child 1233 228c94f0b5dc
Added optimized C 32bit RGB<->RGBA alpha masking blitter from Alex Volkov.
Fixes Bugzilla #11.
src/video/SDL_blit_N.c
     1.1 --- a/src/video/SDL_blit_N.c	Thu Jan 05 16:37:46 2006 +0000
     1.2 +++ b/src/video/SDL_blit_N.c	Thu Jan 05 16:40:51 2006 +0000
     1.3 @@ -1991,6 +1991,52 @@
     1.4  		}
     1.5  	}
     1.6  }
     1.7 +
     1.8 +/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
     1.9 +static void Blit4to4MaskAlpha(SDL_BlitInfo *info)
    1.10 +{
    1.11 +	int width = info->d_width;
    1.12 +	int height = info->d_height;
    1.13 +	Uint32 *src = (Uint32 *)info->s_pixels;
    1.14 +	int srcskip = info->s_skip;
    1.15 +	Uint32 *dst = (Uint32 *)info->d_pixels;
    1.16 +	int dstskip = info->d_skip;
    1.17 +	SDL_PixelFormat *srcfmt = info->src;
    1.18 +	SDL_PixelFormat *dstfmt = info->dst;
    1.19 +
    1.20 +	if (dstfmt->Amask) {
    1.21 +		/* RGB->RGBA, SET_ALPHA */
    1.22 +		Uint32 mask = (srcfmt->alpha >> dstfmt->Aloss) << dstfmt->Ashift;
    1.23 +
    1.24 +		while ( height-- ) {
    1.25 +			DUFFS_LOOP(
    1.26 +			{
    1.27 +				*dst = *src | mask;
    1.28 +				++dst;
    1.29 +				++src;
    1.30 +			},
    1.31 +			width);
    1.32 +			src = (Uint32*)((Uint8*)src + srcskip);
    1.33 +			dst = (Uint32*)((Uint8*)dst + dstskip);
    1.34 +		}
    1.35 +	} else {
    1.36 +		/* RGBA->RGB, NO_ALPHA */
    1.37 +		Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
    1.38 +
    1.39 +		while ( height-- ) {
    1.40 +			DUFFS_LOOP(
    1.41 +			{
    1.42 +				*dst = *src & mask;
    1.43 +				++dst;
    1.44 +				++src;
    1.45 +			},
    1.46 +			width);
    1.47 +			src = (Uint32*)((Uint8*)src + srcskip);
    1.48 +			dst = (Uint32*)((Uint8*)dst + dstskip);
    1.49 +		}
    1.50 +	}
    1.51 +}
    1.52 +
    1.53  static void BlitNtoN(SDL_BlitInfo *info)
    1.54  {
    1.55  	int width = info->d_width;
    1.56 @@ -2414,8 +2460,18 @@
    1.57  		}
    1.58  		sdata->aux_data = table[which].aux_data;
    1.59  		blitfun = table[which].blitfunc;
    1.60 -		if(a_need == COPY_ALPHA && blitfun == BlitNtoN)
    1.61 -		    blitfun = BlitNtoNCopyAlpha;
    1.62 +
    1.63 +		if(blitfun == BlitNtoN) {  /* default C fallback catch-all. Slow! */
    1.64 +			/* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
    1.65 +			if ( srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4 &&
    1.66 +			     srcfmt->Rmask == dstfmt->Rmask &&
    1.67 +			     srcfmt->Gmask == dstfmt->Gmask &&
    1.68 +			     srcfmt->Bmask == dstfmt->Bmask ) {
    1.69 +				blitfun = Blit4to4MaskAlpha;
    1.70 +			} else if ( a_need == COPY_ALPHA ) {
    1.71 +			    blitfun = BlitNtoNCopyAlpha;
    1.72 +			}
    1.73 +		}
    1.74  	}
    1.75  
    1.76  #ifdef DEBUG_ASM