📄 sdl_blit_n.c
字号:
{
Uint32 pixel;
unsigned sR;
unsigned sG;
unsigned sB;
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
dst += dstbpp;
src += srcbpp;
},
width);
src += srcskip;
dst += dstskip;
}
}
static void BlitNtoNCopyAlpha(SDL_BlitInfo *info)
{
int width = info->d_width;
int height = info->d_height;
Uint8 *src = info->s_pixels;
int srcskip = info->s_skip;
Uint8 *dst = info->d_pixels;
int dstskip = info->d_skip;
SDL_PixelFormat *srcfmt = info->src;
int srcbpp = srcfmt->BytesPerPixel;
SDL_PixelFormat *dstfmt = info->dst;
int dstbpp = dstfmt->BytesPerPixel;
int c;
/* FIXME: should map alpha to [0..255] correctly! */
while ( height-- ) {
for ( c=width; c; --c ) {
Uint32 pixel;
unsigned sR, sG, sB, sA;
DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel,
sR, sG, sB, sA);
ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
sR, sG, sB, sA);
dst += dstbpp;
src += srcbpp;
}
src += srcskip;
dst += dstskip;
}
}
static void BlitNto1Key(SDL_BlitInfo *info)
{
int width = info->d_width;
int height = info->d_height;
Uint8 *src = info->s_pixels;
int srcskip = info->s_skip;
Uint8 *dst = info->d_pixels;
int dstskip = info->d_skip;
SDL_PixelFormat *srcfmt = info->src;
const Uint8 *palmap = info->table;
Uint32 ckey = srcfmt->colorkey;
Uint32 rgbmask = ~srcfmt->Amask;
int srcbpp;
Uint32 pixel;
Uint8 sR, sG, sB;
/* Set up some basic variables */
srcbpp = srcfmt->BytesPerPixel;
ckey &= rgbmask;
if ( palmap == NULL ) {
while ( height-- ) {
DUFFS_LOOP(
{
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel,
sR, sG, sB);
if ( (pixel & rgbmask) != ckey ) {
/* Pack RGB into 8bit pixel */
*dst = ((sR>>5)<<(3+2))|
((sG>>5)<<(2)) |
((sB>>6)<<(0)) ;
}
dst++;
src += srcbpp;
},
width);
src += srcskip;
dst += dstskip;
}
} else {
while ( height-- ) {
DUFFS_LOOP(
{
DISEMBLE_RGB(src, srcbpp, srcfmt, pixel,
sR, sG, sB);
if ( (pixel & rgbmask) != ckey ) {
/* Pack RGB into 8bit pixel */
*dst = palmap[((sR>>5)<<(3+2))|
((sG>>5)<<(2)) |
((sB>>6)<<(0)) ];
}
dst++;
src += srcbpp;
},
width);
src += srcskip;
dst += dstskip;
}
}
}
static void Blit2to2Key(SDL_BlitInfo *info)
{
int width = info->d_width;
int height = info->d_height;
Uint16 *srcp = (Uint16 *)info->s_pixels;
int srcskip = info->s_skip;
Uint16 *dstp = (Uint16 *)info->d_pixels;
int dstskip = info->d_skip;
Uint32 ckey = info->src->colorkey;
Uint32 rgbmask = ~info->src->Amask;
/* Set up some basic variables */
srcskip /= 2;
dstskip /= 2;
ckey &= rgbmask;
while ( height-- ) {
DUFFS_LOOP(
{
if ( (*srcp & rgbmask) != ckey ) {
*dstp = *srcp;
}
dstp++;
srcp++;
},
width);
srcp += srcskip;
dstp += dstskip;
}
}
static void BlitNtoNKey(SDL_BlitInfo *info)
{
int width = info->d_width;
int height = info->d_height;
Uint8 *src = info->s_pixels;
int srcskip = info->s_skip;
Uint8 *dst = info->d_pixels;
int dstskip = info->d_skip;
Uint32 ckey = info->src->colorkey;
SDL_PixelFormat *srcfmt = info->src;
SDL_PixelFormat *dstfmt = info->dst;
int srcbpp = srcfmt->BytesPerPixel;
int dstbpp = dstfmt->BytesPerPixel;
unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
while ( height-- ) {
DUFFS_LOOP(
{
Uint32 pixel;
unsigned sR;
unsigned sG;
unsigned sB;
RETRIEVE_RGB_PIXEL(src, srcbpp, pixel);
if ( pixel != ckey ) {
RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB);
ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
sR, sG, sB, alpha);
}
dst += dstbpp;
src += srcbpp;
},
width);
src += srcskip;
dst += dstskip;
}
}
static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info)
{
int width = info->d_width;
int height = info->d_height;
Uint8 *src = info->s_pixels;
int srcskip = info->s_skip;
Uint8 *dst = info->d_pixels;
int dstskip = info->d_skip;
Uint32 ckey = info->src->colorkey;
SDL_PixelFormat *srcfmt = info->src;
SDL_PixelFormat *dstfmt = info->dst;
Uint32 rgbmask = ~srcfmt->Amask;
Uint8 srcbpp;
Uint8 dstbpp;
Uint32 pixel;
Uint8 sR, sG, sB, sA;
/* Set up some basic variables */
srcbpp = srcfmt->BytesPerPixel;
dstbpp = dstfmt->BytesPerPixel;
ckey &= rgbmask;
/* FIXME: should map alpha to [0..255] correctly! */
while ( height-- ) {
DUFFS_LOOP(
{
DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel,
sR, sG, sB, sA);
if ( (pixel & rgbmask) != ckey ) {
ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
sR, sG, sB, sA);
}
dst += dstbpp;
src += srcbpp;
},
width);
src += srcskip;
dst += dstskip;
}
}
/* Normal N to N optimized blitters */
struct blit_table {
Uint32 srcR, srcG, srcB;
int dstbpp;
Uint32 dstR, dstG, dstB;
Uint32 cpu_flags;
void *aux_data;
SDL_loblit blitfunc;
enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha;
};
static const struct blit_table normal_blit_1[] = {
/* Default for 8-bit RGB source, an invalid combination */
{ 0,0,0, 0, 0,0,0, 0, NULL, NULL },
};
static const struct blit_table normal_blit_2[] = {
#ifdef USE_ASMBLIT
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800,
0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA },
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F,
0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA },
{ 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00,
0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA },
#endif
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF,
0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA },
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000,
0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA },
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00,
0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA },
{ 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000,
0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA },
/* Default for 16-bit RGB source, used if no other blitter matches */
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table normal_blit_3[] = {
/* Default for 24-bit RGB source, never optimized */
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table normal_blit_4[] = {
#ifdef USE_ASMBLIT
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
MMX_CPU, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
MMX_CPU, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
MMX_CPU, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
MMX_CPU, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000,
0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000,
0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00,
0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000,
0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA },
#else
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
0, NULL, Blit_RGB888_RGB565, NO_ALPHA },
{ 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
0, NULL, Blit_RGB888_RGB555, NO_ALPHA },
#endif
/* Default for 32-bit RGB source, used if no other blitter matches */
{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table *normal_blit[] = {
normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
};
SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index)
{
struct private_swaccel *sdata;
SDL_PixelFormat *srcfmt;
SDL_PixelFormat *dstfmt;
const struct blit_table *table;
int which;
SDL_loblit blitfun;
/* Set up data for choosing the blit */
sdata = surface->map->sw_data;
srcfmt = surface->format;
dstfmt = surface->map->dst->format;
if ( blit_index & 2 ) {
/* alpha or alpha+colorkey */
return SDL_CalculateAlphaBlit(surface, blit_index);
}
/* We don't support destinations less than 8-bits */
if ( dstfmt->BitsPerPixel < 8 ) {
return(NULL);
}
if(blit_index == 1) {
/* colorkey blit: Here we don't have too many options, mostly
because RLE is the preferred fast way to deal with this.
If a particular case turns out to be useful we'll add it. */
if(srcfmt->BytesPerPixel == 2
&& surface->map->identity)
return Blit2to2Key;
else if(dstfmt->BytesPerPixel == 1)
return BlitNto1Key;
else {
if(srcfmt->Amask && dstfmt->Amask)
return BlitNtoNKeyCopyAlpha;
else
return BlitNtoNKey;
}
}
blitfun = NULL;
if ( dstfmt->BitsPerPixel == 8 ) {
/* We assume 8-bit destinations are palettized */
if ( (srcfmt->BytesPerPixel == 4) &&
(srcfmt->Rmask == 0x00FF0000) &&
(srcfmt->Gmask == 0x0000FF00) &&
(srcfmt->Bmask == 0x000000FF) ) {
if ( surface->map->table ) {
blitfun = Blit_RGB888_index8_map;
} else {
#ifdef USE_ASMBLIT
sdata->aux_data = ConvertX86p32_8RGB332;
blitfun = ConvertX86;
#else
blitfun = Blit_RGB888_index8;
#endif
}
} else {
blitfun = BlitNto1;
}
} else {
/* Now the meat, choose the blitter we want */
int a_need = 0;
if(dstfmt->Amask)
a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
table = normal_blit[srcfmt->BytesPerPixel-1];
for ( which=0; table[which].srcR; ++which ) {
if ( srcfmt->Rmask == table[which].srcR &&
srcfmt->Gmask == table[which].srcG &&
srcfmt->Bmask == table[which].srcB &&
dstfmt->BytesPerPixel == table[which].dstbpp &&
dstfmt->Rmask == table[which].dstR &&
dstfmt->Gmask == table[which].dstG &&
dstfmt->Bmask == table[which].dstB &&
(a_need & table[which].alpha) == a_need &&
(CPU_Flags()&table[which].cpu_flags) ==
table[which].cpu_flags )
break;
}
sdata->aux_data = table[which].aux_data;
blitfun = table[which].blitfunc;
if(a_need == COPY_ALPHA && blitfun == BlitNtoN)
blitfun = BlitNtoNCopyAlpha;
}
#ifdef DEBUG_ASM
#ifdef USE_ASMBLIT
if ( blitfun == ConvertMMX )
fprintf(stderr, "Using mmx blit\n");
else
if ( blitfun == ConvertX86 )
fprintf(stderr, "Using asm blit\n");
else
#endif
if ( (blitfun == SDL_BlitNtoN) || (blitfun == SDL_BlitNto1) )
fprintf(stderr, "Using C blit\n");
else
fprintf(stderr, "Using optimized C blit\n");
#endif /* DEBUG_ASM */
return(blitfun);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -