Added surface conversion support for ARGB2101010 formats
authorSam Lantinga <slouken@libsdl.org>
Sun, 07 Jul 2013 12:34:21 -0700
changeset 7373 5e6efd29b461
parent 7372 f90f720b9e56
child 7374 29ace61fca99
Added surface conversion support for ARGB2101010 formats
src/video/SDL_blit.h
src/video/SDL_blit_N.c
--- a/src/video/SDL_blit.h	Sun Jul 07 10:31:01 2013 -0700
+++ b/src/video/SDL_blit.h	Sun Jul 07 12:34:21 2013 -0700
@@ -249,6 +249,14 @@
 {                                                                       \
     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 @@
     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) {                                                      \
--- a/src/video/SDL_blit_N.c	Sun Jul 07 10:31:01 2013 -0700
+++ b/src/video/SDL_blit_N.c	Sun Jul 07 12:34:21 2013 -0700
@@ -2363,6 +2363,70 @@
     }
 }
 
+/* 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_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_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 @@
             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;