From 50aa1d7b12db83d64488c286d964e849d506292b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 7 Jul 2013 12:34:21 -0700 Subject: [PATCH] Added surface conversion support for ARGB2101010 formats --- src/video/SDL_blit.h | 15 ++++++ src/video/SDL_blit_N.c | 118 ++++++++++++++++++++++++++++++----------- 2 files changed, 102 insertions(+), 31 deletions(-) diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h index 17615576e..413483496 100644 --- a/src/video/SDL_blit.h +++ b/src/video/SDL_blit.h @@ -249,6 +249,14 @@ do { \ { \ Pixel = (b<<24)|(g<<16)|(r<<8)|a; \ } +#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a) \ +{ \ + r = r ? ((r << 2) | 0x3) : 0; \ + g = g ? ((g << 2) | 0x3) : 0; \ + b = b ? ((b << 2) | 0x3) : 0; \ + a = (a * 3) / 255; \ + Pixel = (a<<30)|(r<<20)|(g<<10)|b; \ +} #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ { \ switch (bpp) { \ @@ -334,6 +342,13 @@ do { \ b = (Pixel>>24); \ a = (Pixel&0xFF); \ } +#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a) \ +{ \ + r = ((Pixel>>22)&0xFF); \ + g = ((Pixel>>12)&0xFF); \ + b = ((Pixel>>2)&0xFF); \ + a = SDL_expand_byte[6][(Pixel>>30)]; \ +} #define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \ do { \ switch (bpp) { \ diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index ac7fe7153..84c96e2dc 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -2363,6 +2363,70 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) } } +/* Special optimized blit for ARGB 2-10-10-10 --> RGBA */ +static void +Blit2101010toN(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int dstbpp = dstfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB, sA; + + while (height--) { + /* *INDENT-OFF* */ + DUFFS_LOOP( + { + Pixel = *(Uint32 *)src; + RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA); + dst += dstbpp; + src += 4; + }, + width); + /* *INDENT-ON* */ + src += srcskip; + dst += dstskip; + } +} + +/* Special optimized blit for RGBA --> ARGB 2-10-10-10 */ +static void +BlitNto2101010(SDL_BlitInfo * info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + int srcskip = info->src_skip; + Uint8 *dst = info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *srcfmt = info->src_fmt; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 Pixel; + unsigned sR, sG, sB, sA; + + while (height--) { + /* *INDENT-OFF* */ + DUFFS_LOOP( + { + DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); + ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA); + *(Uint32 *)dst = Pixel; + dst += 4; + src += srcbpp; + }, + width); + /* *INDENT-ON* */ + src += srcskip; + dst += dstskip; + } +} + /* Normal N to N optimized blitters */ struct blit_table { @@ -2382,24 +2446,18 @@ static const struct blit_table normal_blit_1[] = { static const struct blit_table normal_blit_2[] = { #if SDL_ALTIVEC_BLITTERS /* has-altivec */ - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, - 0x00000000, + {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, 2, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, - 0x00000000, + {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, 2, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, #endif - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, - 0x000000FF, + {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, - 0x00FF0000, + {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, 0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, - 0x0000FF00, + {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00, 0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, - 0xFF000000, + {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, /* Default for 16-bit RGB source, used if no other blitter matches */ @@ -2414,25 +2472,18 @@ static const struct blit_table normal_blit_3[] = { static const struct blit_table normal_blit_4[] = { #if SDL_ALTIVEC_BLITTERS /* has-altivec | dont-use-prefetch */ - {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, - 0x00000000, - 6, ConvertAltivec32to32_noprefetch, - NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, + 6, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, /* has-altivec */ - {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, - 0x00000000, - 2, ConvertAltivec32to32_prefetch, - NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, + 2, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, /* has-altivec */ - {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, - 0x0000001F, + {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F, 2, Blit_RGB888_RGB565Altivec, NO_ALPHA}, #endif - {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, - 0x0000001F, + {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F, 0, Blit_RGB888_RGB565, NO_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, - 0x0000001F, + {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F, 0, Blit_RGB888_RGB555, NO_ALPHA}, /* Default for 32-bit RGB source, used if no other blitter matches */ {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} @@ -2502,11 +2553,16 @@ SDL_CalculateBlitN(SDL_Surface * surface) blitfun = table[which].blitfunc; 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) { + if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) { + blitfun = Blit2101010toN; + } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) { + blitfun = BlitNto2101010; + } else if (srcfmt->BytesPerPixel == 4 && + dstfmt->BytesPerPixel == 4 && + srcfmt->Rmask == dstfmt->Rmask && + srcfmt->Gmask == dstfmt->Gmask && + srcfmt->Bmask == dstfmt->Bmask) { + /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */ blitfun = Blit4to4MaskAlpha; } else if (a_need == COPY_ALPHA) { blitfun = BlitNtoNCopyAlpha;