Added surface conversion support for ARGB2101010 formats
authorSam Lantinga <slouken@libsdl.org>
Sun, 07 Jul 2013 12:34:21 -0700
changeset 73735e6efd29b461
parent 7372 f90f720b9e56
child 7374 29ace61fca99
Added surface conversion support for ARGB2101010 formats
src/video/SDL_blit.h
src/video/SDL_blit_N.c
     1.1 --- a/src/video/SDL_blit.h	Sun Jul 07 10:31:01 2013 -0700
     1.2 +++ b/src/video/SDL_blit.h	Sun Jul 07 12:34:21 2013 -0700
     1.3 @@ -249,6 +249,14 @@
     1.4  {                                                                       \
     1.5      Pixel = (b<<24)|(g<<16)|(r<<8)|a;                                   \
     1.6  }
     1.7 +#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a)                        \
     1.8 +{                                                                       \
     1.9 +    r = r ? ((r << 2) | 0x3) : 0;                                       \
    1.10 +    g = g ? ((g << 2) | 0x3) : 0;                                       \
    1.11 +    b = b ? ((b << 2) | 0x3) : 0;                                       \
    1.12 +    a = (a * 3) / 255;                                                  \
    1.13 +    Pixel = (a<<30)|(r<<20)|(g<<10)|b;                                  \
    1.14 +}
    1.15  #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b)                            \
    1.16  {                                                                       \
    1.17      switch (bpp) {                                                      \
    1.18 @@ -334,6 +342,13 @@
    1.19      b = (Pixel>>24);                                                    \
    1.20      a = (Pixel&0xFF);                                                   \
    1.21  }
    1.22 +#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a)                        \
    1.23 +{                                                                       \
    1.24 +    r = ((Pixel>>22)&0xFF);                                             \
    1.25 +    g = ((Pixel>>12)&0xFF);                                             \
    1.26 +    b = ((Pixel>>2)&0xFF);                                              \
    1.27 +    a = SDL_expand_byte[6][(Pixel>>30)];                                \
    1.28 +}
    1.29  #define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a)                 \
    1.30  do {                                                                    \
    1.31      switch (bpp) {                                                      \
     2.1 --- a/src/video/SDL_blit_N.c	Sun Jul 07 10:31:01 2013 -0700
     2.2 +++ b/src/video/SDL_blit_N.c	Sun Jul 07 12:34:21 2013 -0700
     2.3 @@ -2363,6 +2363,70 @@
     2.4      }
     2.5  }
     2.6  
     2.7 +/* Special optimized blit for ARGB 2-10-10-10 --> RGBA */
     2.8 +static void
     2.9 +Blit2101010toN(SDL_BlitInfo * info)
    2.10 +{
    2.11 +    int width = info->dst_w;
    2.12 +    int height = info->dst_h;
    2.13 +    Uint8 *src = info->src;
    2.14 +    int srcskip = info->src_skip;
    2.15 +    Uint8 *dst = info->dst;
    2.16 +    int dstskip = info->dst_skip;
    2.17 +    SDL_PixelFormat *dstfmt = info->dst_fmt;
    2.18 +    int dstbpp = dstfmt->BytesPerPixel;
    2.19 +    Uint32 Pixel;
    2.20 +    unsigned sR, sG, sB, sA;
    2.21 +
    2.22 +    while (height--) {
    2.23 +        /* *INDENT-OFF* */
    2.24 +        DUFFS_LOOP(
    2.25 +        {
    2.26 +            Pixel = *(Uint32 *)src;
    2.27 +            RGBA_FROM_ARGB2101010(Pixel, sR, sG, sB, sA);
    2.28 +            ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
    2.29 +            dst += dstbpp;
    2.30 +            src += 4;
    2.31 +        },
    2.32 +        width);
    2.33 +        /* *INDENT-ON* */
    2.34 +        src += srcskip;
    2.35 +        dst += dstskip;
    2.36 +    }
    2.37 +}
    2.38 +
    2.39 +/* Special optimized blit for RGBA --> ARGB 2-10-10-10 */
    2.40 +static void
    2.41 +BlitNto2101010(SDL_BlitInfo * info)
    2.42 +{
    2.43 +    int width = info->dst_w;
    2.44 +    int height = info->dst_h;
    2.45 +    Uint8 *src = info->src;
    2.46 +    int srcskip = info->src_skip;
    2.47 +    Uint8 *dst = info->dst;
    2.48 +    int dstskip = info->dst_skip;
    2.49 +    SDL_PixelFormat *srcfmt = info->src_fmt;
    2.50 +    int srcbpp = srcfmt->BytesPerPixel;
    2.51 +    Uint32 Pixel;
    2.52 +    unsigned sR, sG, sB, sA;
    2.53 +
    2.54 +    while (height--) {
    2.55 +        /* *INDENT-OFF* */
    2.56 +        DUFFS_LOOP(
    2.57 +        {
    2.58 +            DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
    2.59 +            ARGB2101010_FROM_RGBA(Pixel, sR, sG, sB, sA);
    2.60 +            *(Uint32 *)dst = Pixel;
    2.61 +            dst += 4;
    2.62 +            src += srcbpp;
    2.63 +        },
    2.64 +        width);
    2.65 +        /* *INDENT-ON* */
    2.66 +        src += srcskip;
    2.67 +        dst += dstskip;
    2.68 +    }
    2.69 +}
    2.70 +
    2.71  /* Normal N to N optimized blitters */
    2.72  struct blit_table
    2.73  {
    2.74 @@ -2382,24 +2446,18 @@
    2.75  static const struct blit_table normal_blit_2[] = {
    2.76  #if SDL_ALTIVEC_BLITTERS
    2.77      /* has-altivec */
    2.78 -    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000,
    2.79 -     0x00000000,
    2.80 +    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
    2.81       2, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
    2.82 -    {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000,
    2.83 -     0x00000000,
    2.84 +    {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000,
    2.85       2, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
    2.86  #endif
    2.87 -    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00,
    2.88 -     0x000000FF,
    2.89 +    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF,
    2.90       0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
    2.91 -    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00,
    2.92 -     0x00FF0000,
    2.93 +    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000,
    2.94       0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
    2.95 -    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000,
    2.96 -     0x0000FF00,
    2.97 +    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00,
    2.98       0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
    2.99 -    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000,
   2.100 -     0xFF000000,
   2.101 +    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
   2.102       0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
   2.103  
   2.104      /* Default for 16-bit RGB source, used if no other blitter matches */
   2.105 @@ -2414,25 +2472,18 @@
   2.106  static const struct blit_table normal_blit_4[] = {
   2.107  #if SDL_ALTIVEC_BLITTERS
   2.108      /* has-altivec | dont-use-prefetch */
   2.109 -    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000,
   2.110 -     0x00000000,
   2.111 -     6, ConvertAltivec32to32_noprefetch,
   2.112 -     NO_ALPHA | COPY_ALPHA | SET_ALPHA},
   2.113 +    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
   2.114 +     6, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
   2.115      /* has-altivec */
   2.116 -    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000,
   2.117 -     0x00000000,
   2.118 -     2, ConvertAltivec32to32_prefetch,
   2.119 -     NO_ALPHA | COPY_ALPHA | SET_ALPHA},
   2.120 +    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000,
   2.121 +     2, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
   2.122      /* has-altivec */
   2.123 -    {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0,
   2.124 -     0x0000001F,
   2.125 +    {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F,
   2.126       2, Blit_RGB888_RGB565Altivec, NO_ALPHA},
   2.127  #endif
   2.128 -    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0,
   2.129 -     0x0000001F,
   2.130 +    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F,
   2.131       0, Blit_RGB888_RGB565, NO_ALPHA},
   2.132 -    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0,
   2.133 -     0x0000001F,
   2.134 +    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F,
   2.135       0, Blit_RGB888_RGB555, NO_ALPHA},
   2.136      /* Default for 32-bit RGB source, used if no other blitter matches */
   2.137      {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
   2.138 @@ -2502,11 +2553,16 @@
   2.139              blitfun = table[which].blitfunc;
   2.140  
   2.141              if (blitfun == BlitNtoN) {  /* default C fallback catch-all. Slow! */
   2.142 -                /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
   2.143 -                if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4
   2.144 -                    && srcfmt->Rmask == dstfmt->Rmask
   2.145 -                    && srcfmt->Gmask == dstfmt->Gmask
   2.146 -                    && srcfmt->Bmask == dstfmt->Bmask) {
   2.147 +                if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
   2.148 +                    blitfun = Blit2101010toN;
   2.149 +                } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) {
   2.150 +                    blitfun = BlitNto2101010;
   2.151 +                } else if (srcfmt->BytesPerPixel == 4 &&
   2.152 +                            dstfmt->BytesPerPixel == 4 &&
   2.153 +                            srcfmt->Rmask == dstfmt->Rmask &&
   2.154 +                            srcfmt->Gmask == dstfmt->Gmask &&
   2.155 +                            srcfmt->Bmask == dstfmt->Bmask) {
   2.156 +                    /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
   2.157                      blitfun = Blit4to4MaskAlpha;
   2.158                  } else if (a_need == COPY_ALPHA) {
   2.159                      blitfun = BlitNtoNCopyAlpha;