Added 8-bit RGB source surface support to NtoN blitters

This commit is contained in:
Sam Lantinga 2013-07-06 21:17:09 -07:00
parent 185f93a7a9
commit c9acdd87a7
2 changed files with 326 additions and 296 deletions

View file

@ -118,289 +118,319 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface * surface);
#endif #endif
/* Load pixel of the specified format from a buffer and get its R-G-B values */ /* Load pixel of the specified format from a buffer and get its R-G-B values */
#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \ #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \
{ \ { \
r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \ r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \ g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \ b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
} }
#define RGB_FROM_RGB565(Pixel, r, g, b) \ #define RGB_FROM_RGB565(Pixel, r, g, b) \
{ \ { \
r = SDL_expand_byte[3][((Pixel&0xF800)>>11)]; \ r = SDL_expand_byte[3][((Pixel&0xF800)>>11)]; \
g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; \ g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; \
b = SDL_expand_byte[3][(Pixel&0x001F)]; \ b = SDL_expand_byte[3][(Pixel&0x001F)]; \
} }
#define RGB_FROM_RGB555(Pixel, r, g, b) \ #define RGB_FROM_RGB555(Pixel, r, g, b) \
{ \ { \
r = SDL_expand_byte[3][((Pixel&0x7C00)>>10)]; \ r = SDL_expand_byte[3][((Pixel&0x7C00)>>10)]; \
g = SDL_expand_byte[3][((Pixel&0x03E0)>>5)]; \ g = SDL_expand_byte[3][((Pixel&0x03E0)>>5)]; \
b = SDL_expand_byte[3][(Pixel&0x001F)]; \ b = SDL_expand_byte[3][(Pixel&0x001F)]; \
} }
#define RGB_FROM_RGB888(Pixel, r, g, b) \ #define RGB_FROM_RGB888(Pixel, r, g, b) \
{ \ { \
r = ((Pixel&0xFF0000)>>16); \ r = ((Pixel&0xFF0000)>>16); \
g = ((Pixel&0xFF00)>>8); \ g = ((Pixel&0xFF00)>>8); \
b = (Pixel&0xFF); \ b = (Pixel&0xFF); \
} }
#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \ #define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \
do { \ do { \
switch (bpp) { \ switch (bpp) { \
case 2: \ case 1: \
Pixel = *((Uint16 *)(buf)); \ Pixel = *((Uint8 *)(buf)); \
break; \ break; \
\ \
case 3: { \ case 2: \
Uint8 *B = (Uint8 *)(buf); \ Pixel = *((Uint16 *)(buf)); \
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ break; \
Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ \
} else { \ case 3: { \
Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ Uint8 *B = (Uint8 *)(buf); \
} \ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
} \ Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
break; \ } else { \
\ Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
case 4: \ } \
Pixel = *((Uint32 *)(buf)); \ } \
break; \ break; \
\ \
default: \ case 4: \
Pixel = 0; /* stop gcc complaints */ \ Pixel = *((Uint32 *)(buf)); \
break; \ break; \
} \ \
default: \
Pixel = 0; /* stop gcc complaints */ \
break; \
} \
} while (0) } while (0)
#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \ #define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \
do { \ do { \
switch (bpp) { \ switch (bpp) { \
case 2: \ case 1: \
Pixel = *((Uint16 *)(buf)); \ Pixel = *((Uint8 *)(buf)); \
RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
break; \ break; \
\ \
case 3: { \ case 2: \
Pixel = 0; \ Pixel = *((Uint16 *)(buf)); \
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
r = *((buf)+fmt->Rshift/8); \ break; \
g = *((buf)+fmt->Gshift/8); \ \
b = *((buf)+fmt->Bshift/8); \ case 3: { \
} else { \ Pixel = 0; \
r = *((buf)+2-fmt->Rshift/8); \ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
g = *((buf)+2-fmt->Gshift/8); \ r = *((buf)+fmt->Rshift/8); \
b = *((buf)+2-fmt->Bshift/8); \ g = *((buf)+fmt->Gshift/8); \
} \ b = *((buf)+fmt->Bshift/8); \
} \ } else { \
break; \ r = *((buf)+2-fmt->Rshift/8); \
\ g = *((buf)+2-fmt->Gshift/8); \
case 4: \ b = *((buf)+2-fmt->Bshift/8); \
Pixel = *((Uint32 *)(buf)); \ } \
RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ } \
break; \ break; \
\ \
default: \ case 4: \
/* stop gcc complaints */ \ Pixel = *((Uint32 *)(buf)); \
Pixel = 0; \ RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
r = g = b = 0; \ break; \
break; \ \
} \ default: \
/* stop gcc complaints */ \
Pixel = 0; \
r = g = b = 0; \
break; \
} \
} while (0) } while (0)
/* Assemble R-G-B values into a specified pixel format and store them */ /* Assemble R-G-B values into a specified pixel format and store them */
#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ #define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \
{ \ { \
Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
((g>>fmt->Gloss)<<fmt->Gshift)| \ ((g>>fmt->Gloss)<<fmt->Gshift)| \
((b>>fmt->Bloss)<<fmt->Bshift)| \ ((b>>fmt->Bloss)<<fmt->Bshift)| \
fmt->Amask; \ fmt->Amask; \
} }
#define RGB565_FROM_RGB(Pixel, r, g, b) \ #define RGB565_FROM_RGB(Pixel, r, g, b) \
{ \ { \
Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \ Pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \
} }
#define RGB555_FROM_RGB(Pixel, r, g, b) \ #define RGB555_FROM_RGB(Pixel, r, g, b) \
{ \ { \
Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \ Pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \
} }
#define RGB888_FROM_RGB(Pixel, r, g, b) \ #define RGB888_FROM_RGB(Pixel, r, g, b) \
{ \ { \
Pixel = (r<<16)|(g<<8)|b; \ Pixel = (r<<16)|(g<<8)|b; \
} }
#define ARGB8888_FROM_RGBA(Pixel, r, g, b, a) \ #define ARGB8888_FROM_RGBA(Pixel, r, g, b, a) \
{ \ { \
Pixel = (a<<24)|(r<<16)|(g<<8)|b; \ Pixel = (a<<24)|(r<<16)|(g<<8)|b; \
} }
#define RGBA8888_FROM_RGBA(Pixel, r, g, b, a) \ #define RGBA8888_FROM_RGBA(Pixel, r, g, b, a) \
{ \ { \
Pixel = (r<<24)|(g<<16)|(b<<8)|a; \ Pixel = (r<<24)|(g<<16)|(b<<8)|a; \
} }
#define ABGR8888_FROM_RGBA(Pixel, r, g, b, a) \ #define ABGR8888_FROM_RGBA(Pixel, r, g, b, a) \
{ \ { \
Pixel = (a<<24)|(b<<16)|(g<<8)|r; \ Pixel = (a<<24)|(b<<16)|(g<<8)|r; \
} }
#define BGRA8888_FROM_RGBA(Pixel, r, g, b, a) \ #define BGRA8888_FROM_RGBA(Pixel, r, g, b, a) \
{ \ { \
Pixel = (b<<24)|(g<<16)|(r<<8)|a; \ Pixel = (b<<24)|(g<<16)|(r<<8)|a; \
} }
#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \
{ \ { \
switch (bpp) { \ switch (bpp) { \
case 2: { \ case 1: { \
Uint16 Pixel; \ Uint8 Pixel; \
\ \
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
*((Uint16 *)(buf)) = Pixel; \ *((Uint8 *)(buf)) = Pixel; \
} \ } \
break; \ break; \
\ \
case 3: { \ case 2: { \
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ Uint16 Pixel; \
*((buf)+fmt->Rshift/8) = r; \ \
*((buf)+fmt->Gshift/8) = g; \ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
*((buf)+fmt->Bshift/8) = b; \ *((Uint16 *)(buf)) = Pixel; \
} else { \ } \
*((buf)+2-fmt->Rshift/8) = r; \ break; \
*((buf)+2-fmt->Gshift/8) = g; \ \
*((buf)+2-fmt->Bshift/8) = b; \ case 3: { \
} \ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
} \ *((buf)+fmt->Rshift/8) = r; \
break; \ *((buf)+fmt->Gshift/8) = g; \
\ *((buf)+fmt->Bshift/8) = b; \
case 4: { \ } else { \
Uint32 Pixel; \ *((buf)+2-fmt->Rshift/8) = r; \
\ *((buf)+2-fmt->Gshift/8) = g; \
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ *((buf)+2-fmt->Bshift/8) = b; \
*((Uint32 *)(buf)) = Pixel; \ } \
} \ } \
break; \ break; \
} \ \
case 4: { \
Uint32 Pixel; \
\
PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \
*((Uint32 *)(buf)) = Pixel; \
} \
break; \
} \
} }
/* FIXME: Should we rescale alpha into 0..255 here? */ /* FIXME: Should we rescale alpha into 0..255 here? */
#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \ #define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \
{ \ { \
r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \ r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \ g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \ b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
a = SDL_expand_byte[fmt->Aloss][((Pixel&fmt->Amask)>>fmt->Ashift)]; \ a = SDL_expand_byte[fmt->Aloss][((Pixel&fmt->Amask)>>fmt->Ashift)]; \
} }
#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \ #define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \
{ \ { \
r = (Pixel&fmt->Rmask)>>fmt->Rshift; \ r = (Pixel&fmt->Rmask)>>fmt->Rshift; \
g = (Pixel&fmt->Gmask)>>fmt->Gshift; \ g = (Pixel&fmt->Gmask)>>fmt->Gshift; \
b = (Pixel&fmt->Bmask)>>fmt->Bshift; \ b = (Pixel&fmt->Bmask)>>fmt->Bshift; \
a = (Pixel&fmt->Amask)>>fmt->Ashift; \ a = (Pixel&fmt->Amask)>>fmt->Ashift; \
} }
#define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \ #define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \
{ \ { \
r = (Pixel>>24); \ r = (Pixel>>24); \
g = ((Pixel>>16)&0xFF); \ g = ((Pixel>>16)&0xFF); \
b = ((Pixel>>8)&0xFF); \ b = ((Pixel>>8)&0xFF); \
a = (Pixel&0xFF); \ a = (Pixel&0xFF); \
} }
#define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \ #define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \
{ \ { \
r = ((Pixel>>16)&0xFF); \ r = ((Pixel>>16)&0xFF); \
g = ((Pixel>>8)&0xFF); \ g = ((Pixel>>8)&0xFF); \
b = (Pixel&0xFF); \ b = (Pixel&0xFF); \
a = (Pixel>>24); \ a = (Pixel>>24); \
} }
#define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \ #define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \
{ \ { \
r = (Pixel&0xFF); \ r = (Pixel&0xFF); \
g = ((Pixel>>8)&0xFF); \ g = ((Pixel>>8)&0xFF); \
b = ((Pixel>>16)&0xFF); \ b = ((Pixel>>16)&0xFF); \
a = (Pixel>>24); \ a = (Pixel>>24); \
} }
#define RGBA_FROM_BGRA8888(Pixel, r, g, b, a) \ #define RGBA_FROM_BGRA8888(Pixel, r, g, b, a) \
{ \ { \
r = ((Pixel>>8)&0xFF); \ r = ((Pixel>>8)&0xFF); \
g = ((Pixel>>16)&0xFF); \ g = ((Pixel>>16)&0xFF); \
b = (Pixel>>24); \ b = (Pixel>>24); \
a = (Pixel&0xFF); \ a = (Pixel&0xFF); \
} }
#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \ #define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \
do { \ do { \
switch (bpp) { \ switch (bpp) { \
case 2: \ case 1: \
Pixel = *((Uint16 *)(buf)); \ Pixel = *((Uint8 *)(buf)); \
RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
break; \ break; \
\ \
case 3: { \ case 2: \
Pixel = 0; \ Pixel = *((Uint16 *)(buf)); \
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
r = *((buf)+fmt->Rshift/8); \ break; \
g = *((buf)+fmt->Gshift/8); \ \
b = *((buf)+fmt->Bshift/8); \ case 3: { \
} else { \ Pixel = 0; \
r = *((buf)+2-fmt->Rshift/8); \ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
g = *((buf)+2-fmt->Gshift/8); \ r = *((buf)+fmt->Rshift/8); \
b = *((buf)+2-fmt->Bshift/8); \ g = *((buf)+fmt->Gshift/8); \
} \ b = *((buf)+fmt->Bshift/8); \
a = 0xFF; \ } else { \
} \ r = *((buf)+2-fmt->Rshift/8); \
break; \ g = *((buf)+2-fmt->Gshift/8); \
\ b = *((buf)+2-fmt->Bshift/8); \
case 4: \ } \
Pixel = *((Uint32 *)(buf)); \ a = 0xFF; \
RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ } \
break; \ break; \
\ \
default: \ case 4: \
/* stop gcc complaints */ \ Pixel = *((Uint32 *)(buf)); \
Pixel = 0; \ RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \
r = g = b = a = 0; \ break; \
break; \ \
} \ default: \
/* stop gcc complaints */ \
Pixel = 0; \
r = g = b = a = 0; \
break; \
} \
} while (0) } while (0)
/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ /* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ #define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \
{ \ { \
Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \ Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
((g>>fmt->Gloss)<<fmt->Gshift)| \ ((g>>fmt->Gloss)<<fmt->Gshift)| \
((b>>fmt->Bloss)<<fmt->Bshift)| \ ((b>>fmt->Bloss)<<fmt->Bshift)| \
((a>>fmt->Aloss)<<fmt->Ashift); \ ((a>>fmt->Aloss)<<fmt->Ashift); \
} }
#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ #define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
{ \ { \
switch (bpp) { \ switch (bpp) { \
case 2: { \ case 1: { \
Uint16 Pixel; \ Uint8 Pixel; \
\ \
PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \ PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
*((Uint16 *)(buf)) = Pixel; \ *((Uint8 *)(buf)) = Pixel; \
} \ } \
break; \ break; \
\ \
case 3: { \ case 2: { \
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ Uint16 Pixel; \
*((buf)+fmt->Rshift/8) = r; \ \
*((buf)+fmt->Gshift/8) = g; \ PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
*((buf)+fmt->Bshift/8) = b; \ *((Uint16 *)(buf)) = Pixel; \
} else { \ } \
*((buf)+2-fmt->Rshift/8) = r; \ break; \
*((buf)+2-fmt->Gshift/8) = g; \ \
*((buf)+2-fmt->Bshift/8) = b; \ case 3: { \
} \ if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
} \ *((buf)+fmt->Rshift/8) = r; \
break; \ *((buf)+fmt->Gshift/8) = g; \
\ *((buf)+fmt->Bshift/8) = b; \
case 4: { \ } else { \
Uint32 Pixel; \ *((buf)+2-fmt->Rshift/8) = r; \
\ *((buf)+2-fmt->Gshift/8) = g; \
PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \ *((buf)+2-fmt->Bshift/8) = b; \
*((Uint32 *)(buf)) = Pixel; \ } \
} \ } \
break; \ break; \
} \ \
case 4: { \
Uint32 Pixel; \
\
PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
*((Uint32 *)(buf)) = Pixel; \
} \
break; \
} \
} }
/* Blend the RGB values of two Pixels based on a source alpha value */ /* Blend the RGB values of two Pixels based on a source alpha value */
#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \ #define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \
do { \ do { \
dR = ((((int)(sR-dR)*(int)A)/255)+dR); \ dR = ((((int)(sR-dR)*(int)A)/255)+dR); \
dG = ((((int)(sG-dG)*(int)A)/255)+dG); \ dG = ((((int)(sG-dG)*(int)A)/255)+dG); \
dB = ((((int)(sB-dB)*(int)A)/255)+dB); \ dB = ((((int)(sB-dB)*(int)A)/255)+dB); \
} while(0) } while(0)
@ -413,74 +443,74 @@ do { \
#ifdef USE_DUFFS_LOOP #ifdef USE_DUFFS_LOOP
/* 8-times unrolled loop */ /* 8-times unrolled loop */
#define DUFFS_LOOP8(pixel_copy_increment, width) \ #define DUFFS_LOOP8(pixel_copy_increment, width) \
{ int n = (width+7)/8; \ { int n = (width+7)/8; \
switch (width & 7) { \ switch (width & 7) { \
case 0: do { pixel_copy_increment; \ case 0: do { pixel_copy_increment; \
case 7: pixel_copy_increment; \ case 7: pixel_copy_increment; \
case 6: pixel_copy_increment; \ case 6: pixel_copy_increment; \
case 5: pixel_copy_increment; \ case 5: pixel_copy_increment; \
case 4: pixel_copy_increment; \ case 4: pixel_copy_increment; \
case 3: pixel_copy_increment; \ case 3: pixel_copy_increment; \
case 2: pixel_copy_increment; \ case 2: pixel_copy_increment; \
case 1: pixel_copy_increment; \ case 1: pixel_copy_increment; \
} while ( --n > 0 ); \ } while ( --n > 0 ); \
} \ } \
} }
/* 4-times unrolled loop */ /* 4-times unrolled loop */
#define DUFFS_LOOP4(pixel_copy_increment, width) \ #define DUFFS_LOOP4(pixel_copy_increment, width) \
{ int n = (width+3)/4; \ { int n = (width+3)/4; \
switch (width & 3) { \ switch (width & 3) { \
case 0: do { pixel_copy_increment; \ case 0: do { pixel_copy_increment; \
case 3: pixel_copy_increment; \ case 3: pixel_copy_increment; \
case 2: pixel_copy_increment; \ case 2: pixel_copy_increment; \
case 1: pixel_copy_increment; \ case 1: pixel_copy_increment; \
} while (--n > 0); \ } while (--n > 0); \
} \ } \
} }
/* Use the 8-times version of the loop by default */ /* Use the 8-times version of the loop by default */
#define DUFFS_LOOP(pixel_copy_increment, width) \ #define DUFFS_LOOP(pixel_copy_increment, width) \
DUFFS_LOOP8(pixel_copy_increment, width) DUFFS_LOOP8(pixel_copy_increment, width)
/* Special version of Duff's device for even more optimization */ /* Special version of Duff's device for even more optimization */
#define DUFFS_LOOP_124(pixel_copy_increment1, \ #define DUFFS_LOOP_124(pixel_copy_increment1, \
pixel_copy_increment2, \ pixel_copy_increment2, \
pixel_copy_increment4, width) \ pixel_copy_increment4, width) \
{ int n = width; \ { int n = width; \
if (n & 1) { \ if (n & 1) { \
pixel_copy_increment1; n -= 1; \ pixel_copy_increment1; n -= 1; \
} \ } \
if (n & 2) { \ if (n & 2) { \
pixel_copy_increment2; n -= 2; \ pixel_copy_increment2; n -= 2; \
} \ } \
if (n) { \ if (n) { \
n = (n+7)/ 8; \ n = (n+7)/ 8; \
switch (n & 4) { \ switch (n & 4) { \
case 0: do { pixel_copy_increment4; \ case 0: do { pixel_copy_increment4; \
case 4: pixel_copy_increment4; \ case 4: pixel_copy_increment4; \
} while (--n > 0); \ } while (--n > 0); \
} \ } \
} \ } \
} }
#else #else
/* Don't use Duff's device to unroll loops */ /* Don't use Duff's device to unroll loops */
#define DUFFS_LOOP(pixel_copy_increment, width) \ #define DUFFS_LOOP(pixel_copy_increment, width) \
{ int n; \ { int n; \
for ( n=width; n > 0; --n ) { \ for ( n=width; n > 0; --n ) { \
pixel_copy_increment; \ pixel_copy_increment; \
} \ } \
} }
#define DUFFS_LOOP8(pixel_copy_increment, width) \ #define DUFFS_LOOP8(pixel_copy_increment, width) \
DUFFS_LOOP(pixel_copy_increment, width) DUFFS_LOOP(pixel_copy_increment, width)
#define DUFFS_LOOP4(pixel_copy_increment, width) \ #define DUFFS_LOOP4(pixel_copy_increment, width) \
DUFFS_LOOP(pixel_copy_increment, width) DUFFS_LOOP(pixel_copy_increment, width)
#define DUFFS_LOOP_124(pixel_copy_increment1, \ #define DUFFS_LOOP_124(pixel_copy_increment1, \
pixel_copy_increment2, \ pixel_copy_increment2, \
pixel_copy_increment4, width) \ pixel_copy_increment4, width) \
DUFFS_LOOP(pixel_copy_increment1, width) DUFFS_LOOP(pixel_copy_increment1, width)
#endif /* USE_DUFFS_LOOP */ #endif /* USE_DUFFS_LOOP */

View file

@ -2344,8 +2344,8 @@ struct blit_table
{ NO_ALPHA = 1, SET_ALPHA = 2, COPY_ALPHA = 4 } alpha; { NO_ALPHA = 1, SET_ALPHA = 2, COPY_ALPHA = 4 } alpha;
}; };
static const struct blit_table normal_blit_1[] = { static const struct blit_table normal_blit_1[] = {
/* Default for 8-bit RGB source, an invalid combination */ /* Default for 8-bit RGB source, never optimized */
{0, 0, 0, 0, 0, 0, 0, 0, NULL}, {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
}; };
static const struct blit_table normal_blit_2[] = { static const struct blit_table normal_blit_2[] = {