src/video/SDL_blit_N.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 20 Feb 2012 20:56:52 -0500
changeset 6295 a2c60beb6115
parent 6281 e46d6f4b469e
child 6304 9821f5c9b7bd
permissions -rwxr-xr-x
Fixed bug 1424 - Handling of alpha channel in Altivec accelerated blit functions

evilbite 2012-02-19 09:38:21 PST

There is only one Altivec accelerated blit function
(ConvertAltivec32to32_prefetch() or ConvertAltivec32to32_noprefetch(),
depending on the CPU used) that is supposed to handle all alpha combinations.
This works as follows for every pixel line:
1. Blit single pixels until an aligned address is reached
2. Accelerated blit as far as possible
3. Blit single remaining pixels
Part 2. is set up correctly to handle different combinations of the alpha
channels of the participating surfaces. Parts 1. and 3. only do a simple copy
of all the pixel's components from souce to destination. But when the source
surface has no alpha channel (Amask is 0, e.g. the video surface) the surface's
alpha value must be used instead. Otherwise crap (uninitialized data) is being
copied to the destiniation's alpha channel.

The attached patch is a quick'n'dirty solution to the problem. A more
sophisticated solution might require separate functions for different
combinations of the alpha channels of the participating surfaces.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@1402
    21
#include "SDL_config.h"
slouken@0
    22
slouken@0
    23
#include "SDL_video.h"
slouken@1358
    24
#include "SDL_endian.h"
slouken@1358
    25
#include "SDL_cpuinfo.h"
slouken@0
    26
#include "SDL_blit.h"
slouken@0
    27
icculus@6281
    28
#include "SDL_assert.h"
icculus@6281
    29
slouken@0
    30
/* Functions to blit from N-bit surfaces to other surfaces */
slouken@0
    31
slouken@5389
    32
#if SDL_ALTIVEC_BLITTERS
slouken@6165
    33
#ifdef HAVE_ALTIVEC_H
slouken@6165
    34
#include <altivec.h>
slouken@6165
    35
#endif
slouken@5389
    36
#ifdef __MACOSX__
slouken@5389
    37
#include <sys/sysctl.h>
slouken@5389
    38
static size_t
slouken@5389
    39
GetL3CacheSize(void)
slouken@5389
    40
{
slouken@5389
    41
    const char key[] = "hw.l3cachesize";
slouken@5389
    42
    u_int64_t result = 0;
slouken@5389
    43
    size_t typeSize = sizeof(result);
slouken@5389
    44
slouken@5389
    45
slouken@5389
    46
    int err = sysctlbyname(key, &result, &typeSize, NULL, 0);
slouken@5389
    47
    if (0 != err)
slouken@5389
    48
        return 0;
slouken@5389
    49
slouken@5389
    50
    return result;
slouken@5389
    51
}
slouken@5389
    52
#else
slouken@5389
    53
static size_t
slouken@5389
    54
GetL3CacheSize(void)
slouken@5389
    55
{
slouken@5389
    56
    /* XXX: Just guess G4 */
slouken@5389
    57
    return 2097152;
slouken@5389
    58
}
slouken@5389
    59
#endif /* __MACOSX__ */
slouken@5389
    60
slouken@5389
    61
#if (defined(__MACOSX__) && (__GNUC__ < 4))
slouken@5389
    62
#define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
slouken@5389
    63
        (vector unsigned char) ( a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p )
slouken@5389
    64
#define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
slouken@5389
    65
        (vector unsigned short) ( a,b,c,d,e,f,g,h )
slouken@5389
    66
#else
slouken@5389
    67
#define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
slouken@5389
    68
        (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p }
slouken@5389
    69
#define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \
slouken@5389
    70
        (vector unsigned short) { a,b,c,d,e,f,g,h }
slouken@5389
    71
#endif
slouken@5389
    72
slouken@5389
    73
#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F)
slouken@5389
    74
#define VSWIZZLE32(a,b,c,d) (vector unsigned char) \
slouken@5389
    75
                               ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \
slouken@5389
    76
                                 0x04+a, 0x04+b, 0x04+c, 0x04+d, \
slouken@5389
    77
                                 0x08+a, 0x08+b, 0x08+c, 0x08+d, \
slouken@5389
    78
                                 0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d )
slouken@5389
    79
slouken@5389
    80
#define MAKE8888(dstfmt, r, g, b, a)  \
slouken@5389
    81
    ( ((r<<dstfmt->Rshift)&dstfmt->Rmask) | \
slouken@5389
    82
      ((g<<dstfmt->Gshift)&dstfmt->Gmask) | \
slouken@5389
    83
      ((b<<dstfmt->Bshift)&dstfmt->Bmask) | \
slouken@5389
    84
      ((a<<dstfmt->Ashift)&dstfmt->Amask) )
slouken@5389
    85
slouken@5389
    86
/*
slouken@5389
    87
 * Data Stream Touch...Altivec cache prefetching.
slouken@5389
    88
 *
slouken@5389
    89
 *  Don't use this on a G5...however, the speed boost is very significant
slouken@5389
    90
 *   on a G4.
slouken@5389
    91
 */
slouken@5389
    92
#define DST_CHAN_SRC 1
slouken@5389
    93
#define DST_CHAN_DEST 2
slouken@5389
    94
slouken@5389
    95
/* macro to set DST control word value... */
slouken@5389
    96
#define DST_CTRL(size, count, stride) \
slouken@5389
    97
    (((size) << 24) | ((count) << 16) | (stride))
slouken@5389
    98
slouken@5389
    99
#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \
slouken@5389
   100
    ? vec_lvsl(0, src) \
slouken@5389
   101
    : vec_add(vec_lvsl(8, src), vec_splat_u8(8)))
slouken@5389
   102
slouken@5389
   103
/* Calculate the permute vector used for 32->32 swizzling */
slouken@5389
   104
static vector unsigned char
slouken@5389
   105
calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
slouken@5389
   106
{
slouken@5389
   107
    /*
slouken@5389
   108
     * We have to assume that the bits that aren't used by other
slouken@5389
   109
     *  colors is alpha, and it's one complete byte, since some formats
slouken@5389
   110
     *  leave alpha with a zero mask, but we should still swizzle the bits.
slouken@5389
   111
     */
slouken@5389
   112
    /* ARGB */
slouken@5389
   113
    const static const struct SDL_PixelFormat default_pixel_format = {
slouken@5407
   114
        0, NULL, 0, 0,
slouken@6165
   115
        {0, 0},
slouken@6165
   116
        0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
slouken@5389
   117
        0, 0, 0, 0,
slouken@5389
   118
        16, 8, 0, 24,
slouken@5407
   119
        0, NULL
slouken@5389
   120
    };
slouken@5389
   121
    if (!srcfmt) {
slouken@5389
   122
        srcfmt = &default_pixel_format;
slouken@5389
   123
    }
slouken@5389
   124
    if (!dstfmt) {
slouken@5389
   125
        dstfmt = &default_pixel_format;
slouken@5389
   126
    }
slouken@5389
   127
    const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00,
slouken@5389
   128
                                                       0x04, 0x04, 0x04, 0x04,
slouken@5389
   129
                                                       0x08, 0x08, 0x08, 0x08,
slouken@5389
   130
                                                       0x0C, 0x0C, 0x0C,
slouken@5389
   131
                                                       0x0C);
slouken@5389
   132
    vector unsigned char vswiz;
slouken@5389
   133
    vector unsigned int srcvec;
slouken@5389
   134
#define RESHIFT(X) (3 - ((X) >> 3))
slouken@5389
   135
    Uint32 rmask = RESHIFT(srcfmt->Rshift) << (dstfmt->Rshift);
slouken@5389
   136
    Uint32 gmask = RESHIFT(srcfmt->Gshift) << (dstfmt->Gshift);
slouken@5389
   137
    Uint32 bmask = RESHIFT(srcfmt->Bshift) << (dstfmt->Bshift);
slouken@5389
   138
    Uint32 amask;
slouken@5389
   139
    /* Use zero for alpha if either surface doesn't have alpha */
slouken@5389
   140
    if (dstfmt->Amask) {
slouken@5389
   141
        amask =
slouken@5389
   142
            ((srcfmt->Amask) ? RESHIFT(srcfmt->
slouken@5389
   143
                                       Ashift) : 0x10) << (dstfmt->Ashift);
slouken@5389
   144
    } else {
slouken@5389
   145
        amask =
slouken@5389
   146
            0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^
slouken@5389
   147
                          0xFFFFFFFF);
slouken@5389
   148
    }
slouken@5389
   149
#undef RESHIFT
slouken@5389
   150
    ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask);
slouken@5389
   151
    vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0));
slouken@5389
   152
    return (vswiz);
slouken@5389
   153
}
slouken@5389
   154
slouken@5389
   155
static void Blit_RGB888_RGB565(SDL_BlitInfo * info);
slouken@5389
   156
static void
slouken@5389
   157
Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info)
slouken@5389
   158
{
slouken@5389
   159
    int height = info->dst_h;
slouken@5389
   160
    Uint8 *src = (Uint8 *) info->src;
slouken@5389
   161
    int srcskip = info->src_skip;
slouken@5389
   162
    Uint8 *dst = (Uint8 *) info->dst;
slouken@5389
   163
    int dstskip = info->dst_skip;
slouken@5389
   164
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   165
    vector unsigned char valpha = vec_splat_u8(0);
slouken@5389
   166
    vector unsigned char vpermute = calc_swizzle32(srcfmt, NULL);
slouken@5389
   167
    vector unsigned char vgmerge = VECUINT8_LITERAL(0x00, 0x02, 0x00, 0x06,
slouken@5389
   168
                                                    0x00, 0x0a, 0x00, 0x0e,
slouken@5389
   169
                                                    0x00, 0x12, 0x00, 0x16,
slouken@5389
   170
                                                    0x00, 0x1a, 0x00, 0x1e);
slouken@5389
   171
    vector unsigned short v1 = vec_splat_u16(1);
slouken@5389
   172
    vector unsigned short v3 = vec_splat_u16(3);
slouken@5389
   173
    vector unsigned short v3f =
slouken@5389
   174
        VECUINT16_LITERAL(0x003f, 0x003f, 0x003f, 0x003f,
slouken@5389
   175
                          0x003f, 0x003f, 0x003f, 0x003f);
slouken@5389
   176
    vector unsigned short vfc =
slouken@5389
   177
        VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc,
slouken@5389
   178
                          0x00fc, 0x00fc, 0x00fc, 0x00fc);
slouken@5389
   179
    vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7);
slouken@5389
   180
    vf800 = vec_sl(vf800, vec_splat_u16(8));
slouken@5389
   181
slouken@5389
   182
    while (height--) {
slouken@5389
   183
        vector unsigned char valigner;
slouken@5389
   184
        vector unsigned char voverflow;
slouken@5389
   185
        vector unsigned char vsrc;
slouken@5389
   186
slouken@5389
   187
        int width = info->dst_w;
slouken@5389
   188
        int extrawidth;
slouken@5389
   189
slouken@5389
   190
        /* do scalar until we can align... */
slouken@5389
   191
#define ONE_PIXEL_BLEND(condition, widthvar) \
slouken@5389
   192
        while (condition) { \
slouken@5389
   193
            Uint32 Pixel; \
slouken@5389
   194
            unsigned sR, sG, sB, sA; \
slouken@5389
   195
            DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \
slouken@5389
   196
                          sR, sG, sB, sA); \
slouken@5389
   197
            *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \
slouken@5389
   198
                                ((sG << 3) & 0x000007E0) | \
slouken@5389
   199
                                ((sB >> 3) & 0x0000001F)); \
slouken@5389
   200
            dst += 2; \
slouken@5389
   201
            src += 4; \
slouken@5389
   202
            widthvar--; \
slouken@5389
   203
        }
slouken@5389
   204
slouken@5389
   205
        ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
slouken@5389
   206
slouken@5389
   207
        /* After all that work, here's the vector part! */
slouken@5389
   208
        extrawidth = (width % 8);       /* trailing unaligned stores */
slouken@5389
   209
        width -= extrawidth;
slouken@5389
   210
        vsrc = vec_ld(0, src);
slouken@5389
   211
        valigner = VEC_ALIGNER(src);
slouken@5389
   212
slouken@5389
   213
        while (width) {
slouken@5389
   214
            vector unsigned short vpixel, vrpixel, vgpixel, vbpixel;
slouken@5389
   215
            vector unsigned int vsrc1, vsrc2;
slouken@5389
   216
            vector unsigned char vdst;
slouken@5389
   217
slouken@5389
   218
            voverflow = vec_ld(15, src);
slouken@5389
   219
            vsrc = vec_perm(vsrc, voverflow, valigner);
slouken@5389
   220
            vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
slouken@5389
   221
            src += 16;
slouken@5389
   222
            vsrc = voverflow;
slouken@5389
   223
            voverflow = vec_ld(15, src);
slouken@5389
   224
            vsrc = vec_perm(vsrc, voverflow, valigner);
slouken@5389
   225
            vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute);
slouken@5389
   226
            /* 1555 */
slouken@5389
   227
            vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2);
slouken@5389
   228
            vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge);
slouken@5389
   229
            vgpixel = vec_and(vgpixel, vfc);
slouken@5389
   230
            vgpixel = vec_sl(vgpixel, v3);
slouken@5389
   231
            vrpixel = vec_sl(vpixel, v1);
slouken@5389
   232
            vrpixel = vec_and(vrpixel, vf800);
slouken@5389
   233
            vbpixel = vec_and(vpixel, v3f);
slouken@5389
   234
            vdst =
slouken@5389
   235
                vec_or((vector unsigned char) vrpixel,
slouken@5389
   236
                       (vector unsigned char) vgpixel);
slouken@5389
   237
            /* 565 */
slouken@5389
   238
            vdst = vec_or(vdst, (vector unsigned char) vbpixel);
slouken@5389
   239
            vec_st(vdst, 0, dst);
slouken@5389
   240
slouken@5389
   241
            width -= 8;
slouken@5389
   242
            src += 16;
slouken@5389
   243
            dst += 16;
slouken@5389
   244
            vsrc = voverflow;
slouken@5389
   245
        }
slouken@5389
   246
icculus@6281
   247
        SDL_assert(width == 0);
slouken@5389
   248
slouken@5389
   249
        /* do scalar until we can align... */
slouken@5389
   250
        ONE_PIXEL_BLEND((extrawidth), extrawidth);
slouken@5389
   251
#undef ONE_PIXEL_BLEND
slouken@5389
   252
slouken@5389
   253
        src += srcskip;         /* move to next row, accounting for pitch. */
slouken@5389
   254
        dst += dstskip;
slouken@5389
   255
    }
slouken@5389
   256
slouken@5389
   257
slouken@5389
   258
}
slouken@5389
   259
slouken@5389
   260
static void
slouken@5389
   261
Blit_RGB565_32Altivec(SDL_BlitInfo * info)
slouken@5389
   262
{
slouken@5389
   263
    int height = info->dst_h;
slouken@5389
   264
    Uint8 *src = (Uint8 *) info->src;
slouken@5389
   265
    int srcskip = info->src_skip;
slouken@5389
   266
    Uint8 *dst = (Uint8 *) info->dst;
slouken@5389
   267
    int dstskip = info->dst_skip;
slouken@5389
   268
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   269
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@5389
   270
    unsigned alpha;
slouken@5389
   271
    vector unsigned char valpha;
slouken@5389
   272
    vector unsigned char vpermute;
slouken@5389
   273
    vector unsigned short vf800;
slouken@5389
   274
    vector unsigned int v8 = vec_splat_u32(8);
slouken@5389
   275
    vector unsigned int v16 = vec_add(v8, v8);
slouken@5389
   276
    vector unsigned short v2 = vec_splat_u16(2);
slouken@5389
   277
    vector unsigned short v3 = vec_splat_u16(3);
slouken@5389
   278
    /* 
slouken@5389
   279
       0x10 - 0x1f is the alpha
slouken@5389
   280
       0x00 - 0x0e evens are the red
slouken@5389
   281
       0x01 - 0x0f odds are zero
slouken@5389
   282
     */
slouken@5389
   283
    vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
slouken@5389
   284
                                                       0x10, 0x02, 0x01, 0x01,
slouken@5389
   285
                                                       0x10, 0x04, 0x01, 0x01,
slouken@5389
   286
                                                       0x10, 0x06, 0x01,
slouken@5389
   287
                                                       0x01);
slouken@5389
   288
    vector unsigned char vredalpha2 =
slouken@5389
   289
        (vector unsigned
slouken@5389
   290
         char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
slouken@5389
   291
        );
slouken@5389
   292
    /*
slouken@5389
   293
       0x00 - 0x0f is ARxx ARxx ARxx ARxx
slouken@5389
   294
       0x11 - 0x0f odds are blue
slouken@5389
   295
     */
slouken@5389
   296
    vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
slouken@5389
   297
                                                   0x04, 0x05, 0x06, 0x13,
slouken@5389
   298
                                                   0x08, 0x09, 0x0a, 0x15,
slouken@5389
   299
                                                   0x0c, 0x0d, 0x0e, 0x17);
slouken@5389
   300
    vector unsigned char vblue2 =
slouken@5389
   301
        (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
slouken@5389
   302
        );
slouken@5389
   303
    /*
slouken@5389
   304
       0x00 - 0x0f is ARxB ARxB ARxB ARxB
slouken@5389
   305
       0x10 - 0x0e evens are green
slouken@5389
   306
     */
slouken@5389
   307
    vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
slouken@5389
   308
                                                    0x04, 0x05, 0x12, 0x07,
slouken@5389
   309
                                                    0x08, 0x09, 0x14, 0x0b,
slouken@5389
   310
                                                    0x0c, 0x0d, 0x16, 0x0f);
slouken@5389
   311
    vector unsigned char vgreen2 =
slouken@5389
   312
        (vector unsigned
slouken@5389
   313
         char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
slouken@5389
   314
        );
slouken@5389
   315
icculus@6281
   316
    SDL_assert(srcfmt->BytesPerPixel == 2);
icculus@6281
   317
    SDL_assert(dstfmt->BytesPerPixel == 4);
slouken@5389
   318
slouken@5389
   319
    vf800 = (vector unsigned short) vec_splat_u8(-7);
slouken@5389
   320
    vf800 = vec_sl(vf800, vec_splat_u16(8));
slouken@5389
   321
slouken@5389
   322
    if (dstfmt->Amask && info->a) {
slouken@5389
   323
        ((unsigned char *) &valpha)[0] = alpha = info->a;
slouken@5389
   324
        valpha = vec_splat(valpha, 0);
slouken@5389
   325
    } else {
slouken@5389
   326
        alpha = 0;
slouken@5389
   327
        valpha = vec_splat_u8(0);
slouken@5389
   328
    }
slouken@5389
   329
slouken@5389
   330
    vpermute = calc_swizzle32(NULL, dstfmt);
slouken@5389
   331
    while (height--) {
slouken@5389
   332
        vector unsigned char valigner;
slouken@5389
   333
        vector unsigned char voverflow;
slouken@5389
   334
        vector unsigned char vsrc;
slouken@5389
   335
slouken@5389
   336
        int width = info->dst_w;
slouken@5389
   337
        int extrawidth;
slouken@5389
   338
slouken@5389
   339
        /* do scalar until we can align... */
slouken@5389
   340
#define ONE_PIXEL_BLEND(condition, widthvar) \
slouken@5389
   341
        while (condition) { \
slouken@5389
   342
            unsigned sR, sG, sB; \
slouken@5389
   343
            unsigned short Pixel = *((unsigned short *)src); \
slouken@5389
   344
            sR = (Pixel >> 8) & 0xf8; \
slouken@5389
   345
            sG = (Pixel >> 3) & 0xfc; \
slouken@5389
   346
            sB = (Pixel << 3) & 0xf8; \
slouken@5389
   347
            ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
slouken@5389
   348
            src += 2; \
slouken@5389
   349
            dst += 4; \
slouken@5389
   350
            widthvar--; \
slouken@5389
   351
        }
slouken@5389
   352
        ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
slouken@5389
   353
slouken@5389
   354
        /* After all that work, here's the vector part! */
slouken@5389
   355
        extrawidth = (width % 8);       /* trailing unaligned stores */
slouken@5389
   356
        width -= extrawidth;
slouken@5389
   357
        vsrc = vec_ld(0, src);
slouken@5389
   358
        valigner = VEC_ALIGNER(src);
slouken@5389
   359
slouken@5389
   360
        while (width) {
slouken@5389
   361
            vector unsigned short vR, vG, vB;
slouken@5389
   362
            vector unsigned char vdst1, vdst2;
slouken@5389
   363
slouken@5389
   364
            voverflow = vec_ld(15, src);
slouken@5389
   365
            vsrc = vec_perm(vsrc, voverflow, valigner);
slouken@5389
   366
slouken@5389
   367
            vR = vec_and((vector unsigned short) vsrc, vf800);
slouken@5389
   368
            vB = vec_sl((vector unsigned short) vsrc, v3);
slouken@5389
   369
            vG = vec_sl(vB, v2);
slouken@5389
   370
slouken@5389
   371
            vdst1 =
slouken@5389
   372
                (vector unsigned char) vec_perm((vector unsigned char) vR,
slouken@5389
   373
                                                valpha, vredalpha1);
slouken@5389
   374
            vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
slouken@5389
   375
            vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
slouken@5389
   376
            vdst1 = vec_perm(vdst1, valpha, vpermute);
slouken@5389
   377
            vec_st(vdst1, 0, dst);
slouken@5389
   378
slouken@5389
   379
            vdst2 =
slouken@5389
   380
                (vector unsigned char) vec_perm((vector unsigned char) vR,
slouken@5389
   381
                                                valpha, vredalpha2);
slouken@5389
   382
            vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
slouken@5389
   383
            vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
slouken@5389
   384
            vdst2 = vec_perm(vdst2, valpha, vpermute);
slouken@5389
   385
            vec_st(vdst2, 16, dst);
slouken@5389
   386
slouken@5389
   387
            width -= 8;
slouken@5389
   388
            dst += 32;
slouken@5389
   389
            src += 16;
slouken@5389
   390
            vsrc = voverflow;
slouken@5389
   391
        }
slouken@5389
   392
icculus@6281
   393
        SDL_assert(width == 0);
slouken@5389
   394
slouken@5389
   395
slouken@5389
   396
        /* do scalar until we can align... */
slouken@5389
   397
        ONE_PIXEL_BLEND((extrawidth), extrawidth);
slouken@5389
   398
#undef ONE_PIXEL_BLEND
slouken@5389
   399
slouken@5389
   400
        src += srcskip;         /* move to next row, accounting for pitch. */
slouken@5389
   401
        dst += dstskip;
slouken@5389
   402
    }
slouken@5389
   403
slouken@5389
   404
}
slouken@5389
   405
slouken@5389
   406
slouken@5389
   407
static void
slouken@5389
   408
Blit_RGB555_32Altivec(SDL_BlitInfo * info)
slouken@5389
   409
{
slouken@5389
   410
    int height = info->dst_h;
slouken@5389
   411
    Uint8 *src = (Uint8 *) info->src;
slouken@5389
   412
    int srcskip = info->src_skip;
slouken@5389
   413
    Uint8 *dst = (Uint8 *) info->dst;
slouken@5389
   414
    int dstskip = info->dst_skip;
slouken@5389
   415
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   416
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@5389
   417
    unsigned alpha;
slouken@5389
   418
    vector unsigned char valpha;
slouken@5389
   419
    vector unsigned char vpermute;
slouken@5389
   420
    vector unsigned short vf800;
slouken@5389
   421
    vector unsigned int v8 = vec_splat_u32(8);
slouken@5389
   422
    vector unsigned int v16 = vec_add(v8, v8);
slouken@5389
   423
    vector unsigned short v1 = vec_splat_u16(1);
slouken@5389
   424
    vector unsigned short v3 = vec_splat_u16(3);
slouken@5389
   425
    /* 
slouken@5389
   426
       0x10 - 0x1f is the alpha
slouken@5389
   427
       0x00 - 0x0e evens are the red
slouken@5389
   428
       0x01 - 0x0f odds are zero
slouken@5389
   429
     */
slouken@5389
   430
    vector unsigned char vredalpha1 = VECUINT8_LITERAL(0x10, 0x00, 0x01, 0x01,
slouken@5389
   431
                                                       0x10, 0x02, 0x01, 0x01,
slouken@5389
   432
                                                       0x10, 0x04, 0x01, 0x01,
slouken@5389
   433
                                                       0x10, 0x06, 0x01,
slouken@5389
   434
                                                       0x01);
slouken@5389
   435
    vector unsigned char vredalpha2 =
slouken@5389
   436
        (vector unsigned
slouken@5389
   437
         char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16))
slouken@5389
   438
        );
slouken@5389
   439
    /*
slouken@5389
   440
       0x00 - 0x0f is ARxx ARxx ARxx ARxx
slouken@5389
   441
       0x11 - 0x0f odds are blue
slouken@5389
   442
     */
slouken@5389
   443
    vector unsigned char vblue1 = VECUINT8_LITERAL(0x00, 0x01, 0x02, 0x11,
slouken@5389
   444
                                                   0x04, 0x05, 0x06, 0x13,
slouken@5389
   445
                                                   0x08, 0x09, 0x0a, 0x15,
slouken@5389
   446
                                                   0x0c, 0x0d, 0x0e, 0x17);
slouken@5389
   447
    vector unsigned char vblue2 =
slouken@5389
   448
        (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8)
slouken@5389
   449
        );
slouken@5389
   450
    /*
slouken@5389
   451
       0x00 - 0x0f is ARxB ARxB ARxB ARxB
slouken@5389
   452
       0x10 - 0x0e evens are green
slouken@5389
   453
     */
slouken@5389
   454
    vector unsigned char vgreen1 = VECUINT8_LITERAL(0x00, 0x01, 0x10, 0x03,
slouken@5389
   455
                                                    0x04, 0x05, 0x12, 0x07,
slouken@5389
   456
                                                    0x08, 0x09, 0x14, 0x0b,
slouken@5389
   457
                                                    0x0c, 0x0d, 0x16, 0x0f);
slouken@5389
   458
    vector unsigned char vgreen2 =
slouken@5389
   459
        (vector unsigned
slouken@5389
   460
         char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8))
slouken@5389
   461
        );
slouken@5389
   462
icculus@6281
   463
    SDL_assert(srcfmt->BytesPerPixel == 2);
icculus@6281
   464
    SDL_assert(dstfmt->BytesPerPixel == 4);
slouken@5389
   465
slouken@5389
   466
    vf800 = (vector unsigned short) vec_splat_u8(-7);
slouken@5389
   467
    vf800 = vec_sl(vf800, vec_splat_u16(8));
slouken@5389
   468
slouken@5389
   469
    if (dstfmt->Amask && info->a) {
slouken@5389
   470
        ((unsigned char *) &valpha)[0] = alpha = info->a;
slouken@5389
   471
        valpha = vec_splat(valpha, 0);
slouken@5389
   472
    } else {
slouken@5389
   473
        alpha = 0;
slouken@5389
   474
        valpha = vec_splat_u8(0);
slouken@5389
   475
    }
slouken@5389
   476
slouken@5389
   477
    vpermute = calc_swizzle32(NULL, dstfmt);
slouken@5389
   478
    while (height--) {
slouken@5389
   479
        vector unsigned char valigner;
slouken@5389
   480
        vector unsigned char voverflow;
slouken@5389
   481
        vector unsigned char vsrc;
slouken@5389
   482
slouken@5389
   483
        int width = info->dst_w;
slouken@5389
   484
        int extrawidth;
slouken@5389
   485
slouken@5389
   486
        /* do scalar until we can align... */
slouken@5389
   487
#define ONE_PIXEL_BLEND(condition, widthvar) \
slouken@5389
   488
        while (condition) { \
slouken@5389
   489
            unsigned sR, sG, sB; \
slouken@5389
   490
            unsigned short Pixel = *((unsigned short *)src); \
slouken@5389
   491
            sR = (Pixel >> 7) & 0xf8; \
slouken@5389
   492
            sG = (Pixel >> 2) & 0xf8; \
slouken@5389
   493
            sB = (Pixel << 3) & 0xf8; \
slouken@5389
   494
            ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \
slouken@5389
   495
            src += 2; \
slouken@5389
   496
            dst += 4; \
slouken@5389
   497
            widthvar--; \
slouken@5389
   498
        }
slouken@5389
   499
        ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width);
slouken@5389
   500
slouken@5389
   501
        /* After all that work, here's the vector part! */
slouken@5389
   502
        extrawidth = (width % 8);       /* trailing unaligned stores */
slouken@5389
   503
        width -= extrawidth;
slouken@5389
   504
        vsrc = vec_ld(0, src);
slouken@5389
   505
        valigner = VEC_ALIGNER(src);
slouken@5389
   506
slouken@5389
   507
        while (width) {
slouken@5389
   508
            vector unsigned short vR, vG, vB;
slouken@5389
   509
            vector unsigned char vdst1, vdst2;
slouken@5389
   510
slouken@5389
   511
            voverflow = vec_ld(15, src);
slouken@5389
   512
            vsrc = vec_perm(vsrc, voverflow, valigner);
slouken@5389
   513
slouken@5389
   514
            vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800);
slouken@5389
   515
            vB = vec_sl((vector unsigned short) vsrc, v3);
slouken@5389
   516
            vG = vec_sl(vB, v3);
slouken@5389
   517
slouken@5389
   518
            vdst1 =
slouken@5389
   519
                (vector unsigned char) vec_perm((vector unsigned char) vR,
slouken@5389
   520
                                                valpha, vredalpha1);
slouken@5389
   521
            vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1);
slouken@5389
   522
            vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1);
slouken@5389
   523
            vdst1 = vec_perm(vdst1, valpha, vpermute);
slouken@5389
   524
            vec_st(vdst1, 0, dst);
slouken@5389
   525
slouken@5389
   526
            vdst2 =
slouken@5389
   527
                (vector unsigned char) vec_perm((vector unsigned char) vR,
slouken@5389
   528
                                                valpha, vredalpha2);
slouken@5389
   529
            vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2);
slouken@5389
   530
            vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2);
slouken@5389
   531
            vdst2 = vec_perm(vdst2, valpha, vpermute);
slouken@5389
   532
            vec_st(vdst2, 16, dst);
slouken@5389
   533
slouken@5389
   534
            width -= 8;
slouken@5389
   535
            dst += 32;
slouken@5389
   536
            src += 16;
slouken@5389
   537
            vsrc = voverflow;
slouken@5389
   538
        }
slouken@5389
   539
icculus@6281
   540
        SDL_assert(width == 0);
slouken@5389
   541
slouken@5389
   542
slouken@5389
   543
        /* do scalar until we can align... */
slouken@5389
   544
        ONE_PIXEL_BLEND((extrawidth), extrawidth);
slouken@5389
   545
#undef ONE_PIXEL_BLEND
slouken@5389
   546
slouken@5389
   547
        src += srcskip;         /* move to next row, accounting for pitch. */
slouken@5389
   548
        dst += dstskip;
slouken@5389
   549
    }
slouken@5389
   550
slouken@5389
   551
}
slouken@5389
   552
slouken@5389
   553
static void BlitNtoNKey(SDL_BlitInfo * info);
slouken@5389
   554
static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info);
slouken@5389
   555
static void
slouken@5389
   556
Blit32to32KeyAltivec(SDL_BlitInfo * info)
slouken@5389
   557
{
slouken@5389
   558
    int height = info->dst_h;
slouken@5389
   559
    Uint32 *srcp = (Uint32 *) info->src;
slouken@5389
   560
    int srcskip = info->src_skip / 4;
slouken@5389
   561
    Uint32 *dstp = (Uint32 *) info->dst;
slouken@5389
   562
    int dstskip = info->dst_skip / 4;
slouken@5389
   563
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   564
    int srcbpp = srcfmt->BytesPerPixel;
slouken@5389
   565
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@5389
   566
    int dstbpp = dstfmt->BytesPerPixel;
slouken@5389
   567
    int copy_alpha = (srcfmt->Amask && dstfmt->Amask);
slouken@5389
   568
    unsigned alpha = dstfmt->Amask ? info->a : 0;
slouken@5389
   569
    Uint32 rgbmask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
slouken@5389
   570
    Uint32 ckey = info->colorkey;
slouken@5389
   571
    vector unsigned int valpha;
slouken@5389
   572
    vector unsigned char vpermute;
slouken@5389
   573
    vector unsigned char vzero;
slouken@5389
   574
    vector unsigned int vckey;
slouken@5389
   575
    vector unsigned int vrgbmask;
slouken@5389
   576
    vpermute = calc_swizzle32(srcfmt, dstfmt);
slouken@5389
   577
    if (info->dst_w < 16) {
slouken@5389
   578
        if (copy_alpha) {
slouken@5389
   579
            BlitNtoNKeyCopyAlpha(info);
slouken@5389
   580
        } else {
slouken@5389
   581
            BlitNtoNKey(info);
slouken@5389
   582
        }
slouken@5389
   583
        return;
slouken@5389
   584
    }
slouken@5389
   585
    vzero = vec_splat_u8(0);
slouken@5389
   586
    if (alpha) {
slouken@5389
   587
        ((unsigned char *) &valpha)[0] = (unsigned char) alpha;
slouken@5389
   588
        valpha =
slouken@5389
   589
            (vector unsigned int) vec_splat((vector unsigned char) valpha, 0);
slouken@5389
   590
    } else {
slouken@5389
   591
        valpha = (vector unsigned int) vzero;
slouken@5389
   592
    }
slouken@5389
   593
    ckey &= rgbmask;
slouken@5389
   594
    ((unsigned int *) (char *) &vckey)[0] = ckey;
slouken@5389
   595
    vckey = vec_splat(vckey, 0);
slouken@5389
   596
    ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask;
slouken@5389
   597
    vrgbmask = vec_splat(vrgbmask, 0);
slouken@5389
   598
slouken@5389
   599
    while (height--) {
slouken@5389
   600
#define ONE_PIXEL_BLEND(condition, widthvar) \
slouken@5389
   601
        if (copy_alpha) { \
slouken@5389
   602
            while (condition) { \
slouken@5389
   603
                Uint32 Pixel; \
slouken@5389
   604
                unsigned sR, sG, sB, sA; \
slouken@5389
   605
                DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \
slouken@5389
   606
                          sR, sG, sB, sA); \
slouken@5389
   607
                if ( (Pixel & rgbmask) != ckey ) { \
slouken@5389
   608
                      ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
slouken@5389
   609
                            sR, sG, sB, sA); \
slouken@5389
   610
                } \
slouken@5389
   611
                dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \
slouken@5389
   612
                srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \
slouken@5389
   613
                widthvar--; \
slouken@5389
   614
            } \
slouken@5389
   615
        } else { \
slouken@5389
   616
            while (condition) { \
slouken@5389
   617
                Uint32 Pixel; \
slouken@5389
   618
                unsigned sR, sG, sB; \
slouken@5389
   619
                RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \
slouken@5389
   620
                if ( Pixel != ckey ) { \
slouken@5389
   621
                    RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \
slouken@5389
   622
                    ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \
slouken@5389
   623
                              sR, sG, sB, alpha); \
slouken@5389
   624
                } \
slouken@5389
   625
                dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \
slouken@5389
   626
                srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \
slouken@5389
   627
                widthvar--; \
slouken@5389
   628
            } \
slouken@5389
   629
        }
slouken@5389
   630
        int width = info->dst_w;
slouken@5389
   631
        ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width);
icculus@6281
   632
        SDL_assert(width > 0);
slouken@5389
   633
        if (width > 0) {
slouken@5389
   634
            int extrawidth = (width % 4);
slouken@5389
   635
            vector unsigned char valigner = VEC_ALIGNER(srcp);
slouken@5389
   636
            vector unsigned int vs = vec_ld(0, srcp);
slouken@5389
   637
            width -= extrawidth;
icculus@6281
   638
            SDL_assert(width >= 4);
slouken@5389
   639
            while (width) {
slouken@5389
   640
                vector unsigned char vsel;
slouken@5389
   641
                vector unsigned int vd;
slouken@5389
   642
                vector unsigned int voverflow = vec_ld(15, srcp);
slouken@5389
   643
                /* load the source vec */
slouken@5389
   644
                vs = vec_perm(vs, voverflow, valigner);
slouken@5389
   645
                /* vsel is set for items that match the key */
slouken@5389
   646
                vsel = (vector unsigned char) vec_and(vs, vrgbmask);
slouken@5389
   647
                vsel = (vector unsigned char) vec_cmpeq(vs, vckey);
slouken@5389
   648
                /* permute the src vec to the dest format */
slouken@5389
   649
                vs = vec_perm(vs, valpha, vpermute);
slouken@5389
   650
                /* load the destination vec */
slouken@5389
   651
                vd = vec_ld(0, dstp);
slouken@5389
   652
                /* select the source and dest into vs */
slouken@5389
   653
                vd = (vector unsigned int) vec_sel((vector unsigned char) vs,
slouken@5389
   654
                                                   (vector unsigned char) vd,
slouken@5389
   655
                                                   vsel);
slouken@5389
   656
slouken@5389
   657
                vec_st(vd, 0, dstp);
slouken@5389
   658
                srcp += 4;
slouken@5389
   659
                width -= 4;
slouken@5389
   660
                dstp += 4;
slouken@5389
   661
                vs = voverflow;
slouken@5389
   662
            }
slouken@5389
   663
            ONE_PIXEL_BLEND((extrawidth), extrawidth);
slouken@5389
   664
#undef ONE_PIXEL_BLEND
slouken@5389
   665
            srcp += srcskip;
slouken@5389
   666
            dstp += dstskip;
slouken@5389
   667
        }
slouken@5389
   668
    }
slouken@5389
   669
}
slouken@5389
   670
slouken@5389
   671
/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
slouken@5389
   672
/* Use this on a G5 */
slouken@5389
   673
static void
slouken@5389
   674
ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info)
slouken@5389
   675
{
slouken@5389
   676
    int height = info->dst_h;
slouken@5389
   677
    Uint32 *src = (Uint32 *) info->src;
slouken@5389
   678
    int srcskip = info->src_skip / 4;
slouken@5389
   679
    Uint32 *dst = (Uint32 *) info->dst;
slouken@5389
   680
    int dstskip = info->dst_skip / 4;
slouken@5389
   681
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   682
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@5389
   683
    vector unsigned int vzero = vec_splat_u32(0);
slouken@5389
   684
    vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
slouken@5389
   685
    if (dstfmt->Amask && !srcfmt->Amask) {
slouken@5389
   686
        if (info->a) {
slouken@5389
   687
            vector unsigned char valpha;
slouken@5389
   688
            ((unsigned char *) &valpha)[0] = info->a;
slouken@5389
   689
            vzero = (vector unsigned int) vec_splat(valpha, 0);
slouken@5389
   690
        }
slouken@5389
   691
    }
slouken@5389
   692
icculus@6281
   693
    SDL_assert(srcfmt->BytesPerPixel == 4);
icculus@6281
   694
    SDL_assert(dstfmt->BytesPerPixel == 4);
slouken@5389
   695
slouken@5389
   696
    while (height--) {
slouken@5389
   697
        vector unsigned char valigner;
slouken@5389
   698
        vector unsigned int vbits;
slouken@5389
   699
        vector unsigned int voverflow;
slouken@5389
   700
        Uint32 bits;
slouken@5389
   701
        Uint8 r, g, b, a;
slouken@5389
   702
slouken@5389
   703
        int width = info->dst_w;
slouken@5389
   704
        int extrawidth;
slouken@5389
   705
slouken@5389
   706
        /* do scalar until we can align... */
slouken@5389
   707
        while ((UNALIGNED_PTR(dst)) && (width)) {
slouken@5389
   708
            bits = *(src++);
slouken@5389
   709
            RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
slouken@6295
   710
            if(!srcfmt->Amask)
slouken@6295
   711
              a = srcfmt->alpha;
slouken@5389
   712
            *(dst++) = MAKE8888(dstfmt, r, g, b, a);
slouken@5389
   713
            width--;
slouken@5389
   714
        }
slouken@5389
   715
slouken@5389
   716
        /* After all that work, here's the vector part! */
slouken@5389
   717
        extrawidth = (width % 4);
slouken@5389
   718
        width -= extrawidth;
slouken@5389
   719
        valigner = VEC_ALIGNER(src);
slouken@5389
   720
        vbits = vec_ld(0, src);
slouken@5389
   721
slouken@5389
   722
        while (width) {
slouken@5389
   723
            voverflow = vec_ld(15, src);
slouken@5389
   724
            src += 4;
slouken@5389
   725
            width -= 4;
slouken@5389
   726
            vbits = vec_perm(vbits, voverflow, valigner);       /* src is ready. */
slouken@5389
   727
            vbits = vec_perm(vbits, vzero, vpermute);   /* swizzle it. */
slouken@5389
   728
            vec_st(vbits, 0, dst);      /* store it back out. */
slouken@5389
   729
            dst += 4;
slouken@5389
   730
            vbits = voverflow;
slouken@5389
   731
        }
slouken@5389
   732
icculus@6281
   733
        SDL_assert(width == 0);
slouken@5389
   734
slouken@5389
   735
        /* cover pixels at the end of the row that didn't fit in 16 bytes. */
slouken@5389
   736
        while (extrawidth) {
slouken@5389
   737
            bits = *(src++);    /* max 7 pixels, don't bother with prefetch. */
slouken@5389
   738
            RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
slouken@6295
   739
            if(!srcfmt->Amask)
slouken@6295
   740
              a = srcfmt->alpha;
slouken@5389
   741
            *(dst++) = MAKE8888(dstfmt, r, g, b, a);
slouken@5389
   742
            extrawidth--;
slouken@5389
   743
        }
slouken@5389
   744
slouken@5389
   745
        src += srcskip;
slouken@5389
   746
        dst += dstskip;
slouken@5389
   747
    }
slouken@5389
   748
slouken@5389
   749
}
slouken@5389
   750
slouken@5389
   751
/* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */
slouken@5389
   752
/* Use this on a G4 */
slouken@5389
   753
static void
slouken@5389
   754
ConvertAltivec32to32_prefetch(SDL_BlitInfo * info)
slouken@5389
   755
{
slouken@5389
   756
    const int scalar_dst_lead = sizeof(Uint32) * 4;
slouken@5389
   757
    const int vector_dst_lead = sizeof(Uint32) * 16;
slouken@5389
   758
slouken@5389
   759
    int height = info->dst_h;
slouken@5389
   760
    Uint32 *src = (Uint32 *) info->src;
slouken@5389
   761
    int srcskip = info->src_skip / 4;
slouken@5389
   762
    Uint32 *dst = (Uint32 *) info->dst;
slouken@5389
   763
    int dstskip = info->dst_skip / 4;
slouken@5389
   764
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@5389
   765
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@5389
   766
    vector unsigned int vzero = vec_splat_u32(0);
slouken@5389
   767
    vector unsigned char vpermute = calc_swizzle32(srcfmt, dstfmt);
slouken@5389
   768
    if (dstfmt->Amask && !srcfmt->Amask) {
slouken@5389
   769
        if (info->a) {
slouken@5389
   770
            vector unsigned char valpha;
slouken@5389
   771
            ((unsigned char *) &valpha)[0] = info->a;
slouken@5389
   772
            vzero = (vector unsigned int) vec_splat(valpha, 0);
slouken@5389
   773
        }
slouken@5389
   774
    }
slouken@5389
   775
icculus@6281
   776
    SDL_assert(srcfmt->BytesPerPixel == 4);
icculus@6281
   777
    SDL_assert(dstfmt->BytesPerPixel == 4);
slouken@5389
   778
slouken@5389
   779
    while (height--) {
slouken@5389
   780
        vector unsigned char valigner;
slouken@5389
   781
        vector unsigned int vbits;
slouken@5389
   782
        vector unsigned int voverflow;
slouken@5389
   783
        Uint32 bits;
slouken@5389
   784
        Uint8 r, g, b, a;
slouken@5389
   785
slouken@5389
   786
        int width = info->dst_w;
slouken@5389
   787
        int extrawidth;
slouken@5389
   788
slouken@5389
   789
        /* do scalar until we can align... */
slouken@5389
   790
        while ((UNALIGNED_PTR(dst)) && (width)) {
slouken@5389
   791
            vec_dstt(src + scalar_dst_lead, DST_CTRL(2, 32, 1024),
slouken@5389
   792
                     DST_CHAN_SRC);
slouken@5389
   793
            vec_dstst(dst + scalar_dst_lead, DST_CTRL(2, 32, 1024),
slouken@5389
   794
                      DST_CHAN_DEST);
slouken@5389
   795
            bits = *(src++);
slouken@5389
   796
            RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
slouken@6295
   797
            if(!srcfmt->Amask)
slouken@6295
   798
              a = srcfmt->alpha;
slouken@5389
   799
            *(dst++) = MAKE8888(dstfmt, r, g, b, a);
slouken@5389
   800
            width--;
slouken@5389
   801
        }
slouken@5389
   802
slouken@5389
   803
        /* After all that work, here's the vector part! */
slouken@5389
   804
        extrawidth = (width % 4);
slouken@5389
   805
        width -= extrawidth;
slouken@5389
   806
        valigner = VEC_ALIGNER(src);
slouken@5389
   807
        vbits = vec_ld(0, src);
slouken@5389
   808
slouken@5389
   809
        while (width) {
slouken@5389
   810
            vec_dstt(src + vector_dst_lead, DST_CTRL(2, 32, 1024),
slouken@5389
   811
                     DST_CHAN_SRC);
slouken@5389
   812
            vec_dstst(dst + vector_dst_lead, DST_CTRL(2, 32, 1024),
slouken@5389
   813
                      DST_CHAN_DEST);
slouken@5389
   814
            voverflow = vec_ld(15, src);
slouken@5389
   815
            src += 4;
slouken@5389
   816
            width -= 4;
slouken@5389
   817
            vbits = vec_perm(vbits, voverflow, valigner);       /* src is ready. */
slouken@5389
   818
            vbits = vec_perm(vbits, vzero, vpermute);   /* swizzle it. */
slouken@5389
   819
            vec_st(vbits, 0, dst);      /* store it back out. */
slouken@5389
   820
            dst += 4;
slouken@5389
   821
            vbits = voverflow;
slouken@5389
   822
        }
slouken@5389
   823
icculus@6281
   824
        SDL_assert(width == 0);
slouken@5389
   825
slouken@5389
   826
        /* cover pixels at the end of the row that didn't fit in 16 bytes. */
slouken@5389
   827
        while (extrawidth) {
slouken@5389
   828
            bits = *(src++);    /* max 7 pixels, don't bother with prefetch. */
slouken@5389
   829
            RGBA_FROM_8888(bits, srcfmt, r, g, b, a);
slouken@6295
   830
            if(!srcfmt->Amask)
slouken@6295
   831
              a = srcfmt->alpha;
slouken@5389
   832
            *(dst++) = MAKE8888(dstfmt, r, g, b, a);
slouken@5389
   833
            extrawidth--;
slouken@5389
   834
        }
slouken@5389
   835
slouken@5389
   836
        src += srcskip;
slouken@5389
   837
        dst += dstskip;
slouken@5389
   838
    }
slouken@5389
   839
slouken@5389
   840
    vec_dss(DST_CHAN_SRC);
slouken@5389
   841
    vec_dss(DST_CHAN_DEST);
slouken@5389
   842
}
slouken@5389
   843
slouken@5389
   844
static Uint32
slouken@5389
   845
GetBlitFeatures(void)
slouken@5389
   846
{
slouken@5389
   847
    static Uint32 features = 0xffffffff;
slouken@5389
   848
    if (features == 0xffffffff) {
slouken@5389
   849
        /* Provide an override for testing .. */
slouken@5389
   850
        char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES");
slouken@5389
   851
        if (override) {
slouken@5389
   852
            features = 0;
slouken@5389
   853
            SDL_sscanf(override, "%u", &features);
slouken@5389
   854
        } else {
slouken@5389
   855
            features = (0
slouken@5389
   856
                        /* Feature 1 is has-MMX */
slouken@5389
   857
                        | ((SDL_HasMMX())? 1 : 0)
slouken@5389
   858
                        /* Feature 2 is has-AltiVec */
slouken@5389
   859
                        | ((SDL_HasAltiVec())? 2 : 0)
slouken@5389
   860
                        /* Feature 4 is dont-use-prefetch */
slouken@5389
   861
                        /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */
slouken@5389
   862
                        | ((GetL3CacheSize() == 0) ? 4 : 0)
slouken@5389
   863
                );
slouken@5389
   864
        }
slouken@5389
   865
    }
slouken@5389
   866
    return features;
slouken@5389
   867
}
slouken@5389
   868
slouken@5389
   869
#if __MWERKS__
slouken@5389
   870
#pragma altivec_model off
slouken@5389
   871
#endif
slouken@5389
   872
#else
icculus@1047
   873
/* Feature 1 is has-MMX */
icculus@1047
   874
#define GetBlitFeatures() ((Uint32)(SDL_HasMMX() ? 1 : 0))
slouken@5389
   875
#endif
icculus@1047
   876
icculus@1053
   877
/* This is now endian dependent */
slouken@1443
   878
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
icculus@1053
   879
#define HI	1
icculus@1053
   880
#define LO	0
slouken@1443
   881
#else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
icculus@1053
   882
#define HI	0
icculus@1053
   883
#define LO	1
icculus@1053
   884
#endif
icculus@1053
   885
slouken@0
   886
/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
slouken@0
   887
#define RGB888_RGB332(dst, src) { \
slouken@1428
   888
	dst = (Uint8)((((src)&0x00E00000)>>16)| \
slouken@1428
   889
	              (((src)&0x0000E000)>>11)| \
slouken@1428
   890
	              (((src)&0x000000C0)>>6)); \
slouken@0
   891
}
slouken@1895
   892
static void
slouken@1895
   893
Blit_RGB888_index8(SDL_BlitInfo * info)
slouken@0
   894
{
slouken@0
   895
#ifndef USE_DUFFS_LOOP
slouken@1895
   896
    int c;
slouken@0
   897
#endif
slouken@1895
   898
    int width, height;
slouken@1895
   899
    Uint32 *src;
slouken@1895
   900
    const Uint8 *map;
slouken@1895
   901
    Uint8 *dst;
slouken@1895
   902
    int srcskip, dstskip;
slouken@0
   903
slouken@1895
   904
    /* Set up some basic variables */
slouken@2262
   905
    width = info->dst_w;
slouken@2262
   906
    height = info->dst_h;
slouken@2262
   907
    src = (Uint32 *) info->src;
slouken@2267
   908
    srcskip = info->src_skip / 4;
slouken@2262
   909
    dst = info->dst;
slouken@2267
   910
    dstskip = info->dst_skip;
slouken@1895
   911
    map = info->table;
slouken@0
   912
slouken@1895
   913
    if (map == NULL) {
slouken@1895
   914
        while (height--) {
slouken@0
   915
#ifdef USE_DUFFS_LOOP
slouken@1895
   916
			/* *INDENT-OFF* */
slouken@0
   917
			DUFFS_LOOP(
slouken@0
   918
				RGB888_RGB332(*dst++, *src);
slouken@0
   919
			, width);
slouken@1895
   920
			/* *INDENT-ON* */
slouken@0
   921
#else
slouken@1895
   922
            for (c = width / 4; c; --c) {
slouken@1895
   923
                /* Pack RGB into 8bit pixel */
slouken@1895
   924
                ++src;
slouken@1895
   925
                RGB888_RGB332(*dst++, *src);
slouken@1895
   926
                ++src;
slouken@1895
   927
                RGB888_RGB332(*dst++, *src);
slouken@1895
   928
                ++src;
slouken@1895
   929
                RGB888_RGB332(*dst++, *src);
slouken@1895
   930
                ++src;
slouken@1895
   931
            }
slouken@1895
   932
            switch (width & 3) {
slouken@1895
   933
            case 3:
slouken@1895
   934
                RGB888_RGB332(*dst++, *src);
slouken@1895
   935
                ++src;
slouken@1895
   936
            case 2:
slouken@1895
   937
                RGB888_RGB332(*dst++, *src);
slouken@1895
   938
                ++src;
slouken@1895
   939
            case 1:
slouken@1895
   940
                RGB888_RGB332(*dst++, *src);
slouken@1895
   941
                ++src;
slouken@1895
   942
            }
slouken@0
   943
#endif /* USE_DUFFS_LOOP */
slouken@1895
   944
            src += srcskip;
slouken@1895
   945
            dst += dstskip;
slouken@1895
   946
        }
slouken@1895
   947
    } else {
slouken@1895
   948
        int Pixel;
slouken@0
   949
slouken@1895
   950
        while (height--) {
slouken@0
   951
#ifdef USE_DUFFS_LOOP
slouken@1895
   952
			/* *INDENT-OFF* */
slouken@0
   953
			DUFFS_LOOP(
icculus@1162
   954
				RGB888_RGB332(Pixel, *src);
icculus@1162
   955
				*dst++ = map[Pixel];
slouken@0
   956
				++src;
slouken@0
   957
			, width);
slouken@1895
   958
			/* *INDENT-ON* */
slouken@0
   959
#else
slouken@1895
   960
            for (c = width / 4; c; --c) {
slouken@1895
   961
                /* Pack RGB into 8bit pixel */
slouken@1895
   962
                RGB888_RGB332(Pixel, *src);
slouken@1895
   963
                *dst++ = map[Pixel];
slouken@1895
   964
                ++src;
slouken@1895
   965
                RGB888_RGB332(Pixel, *src);
slouken@1895
   966
                *dst++ = map[Pixel];
slouken@1895
   967
                ++src;
slouken@1895
   968
                RGB888_RGB332(Pixel, *src);
slouken@1895
   969
                *dst++ = map[Pixel];
slouken@1895
   970
                ++src;
slouken@1895
   971
                RGB888_RGB332(Pixel, *src);
slouken@1895
   972
                *dst++ = map[Pixel];
slouken@1895
   973
                ++src;
slouken@1895
   974
            }
slouken@1895
   975
            switch (width & 3) {
slouken@1895
   976
            case 3:
slouken@1895
   977
                RGB888_RGB332(Pixel, *src);
slouken@1895
   978
                *dst++ = map[Pixel];
slouken@1895
   979
                ++src;
slouken@1895
   980
            case 2:
slouken@1895
   981
                RGB888_RGB332(Pixel, *src);
slouken@1895
   982
                *dst++ = map[Pixel];
slouken@1895
   983
                ++src;
slouken@1895
   984
            case 1:
slouken@1895
   985
                RGB888_RGB332(Pixel, *src);
slouken@1895
   986
                *dst++ = map[Pixel];
slouken@1895
   987
                ++src;
slouken@1895
   988
            }
slouken@0
   989
#endif /* USE_DUFFS_LOOP */
slouken@1895
   990
            src += srcskip;
slouken@1895
   991
            dst += dstskip;
slouken@1895
   992
        }
slouken@1895
   993
    }
slouken@0
   994
}
slouken@1895
   995
slouken@0
   996
/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */
slouken@0
   997
#define RGB888_RGB555(dst, src) { \
slouken@1428
   998
	*(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \
slouken@1428
   999
	                            (((*src)&0x0000F800)>>6)| \
slouken@1428
  1000
	                            (((*src)&0x000000F8)>>3)); \
slouken@0
  1001
}
slouken@0
  1002
#define RGB888_RGB555_TWO(dst, src) { \
slouken@0
  1003
	*(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \
slouken@0
  1004
	                     (((src[HI])&0x0000F800)>>6)| \
slouken@0
  1005
	                     (((src[HI])&0x000000F8)>>3))<<16)| \
slouken@0
  1006
	                     (((src[LO])&0x00F80000)>>9)| \
slouken@0
  1007
	                     (((src[LO])&0x0000F800)>>6)| \
slouken@0
  1008
	                     (((src[LO])&0x000000F8)>>3); \
slouken@0
  1009
}
slouken@1895
  1010
static void
slouken@1895
  1011
Blit_RGB888_RGB555(SDL_BlitInfo * info)
slouken@0
  1012
{
slouken@0
  1013
#ifndef USE_DUFFS_LOOP
slouken@1895
  1014
    int c;
slouken@0
  1015
#endif
slouken@1895
  1016
    int width, height;
slouken@1895
  1017
    Uint32 *src;
slouken@1895
  1018
    Uint16 *dst;
slouken@1895
  1019
    int srcskip, dstskip;
slouken@0
  1020
slouken@1895
  1021
    /* Set up some basic variables */
slouken@2262
  1022
    width = info->dst_w;
slouken@2262
  1023
    height = info->dst_h;
slouken@2262
  1024
    src = (Uint32 *) info->src;
slouken@2267
  1025
    srcskip = info->src_skip / 4;
slouken@2262
  1026
    dst = (Uint16 *) info->dst;
slouken@2267
  1027
    dstskip = info->dst_skip / 2;
slouken@0
  1028
slouken@0
  1029
#ifdef USE_DUFFS_LOOP
slouken@1895
  1030
    while (height--) {
slouken@1895
  1031
		/* *INDENT-OFF* */
slouken@0
  1032
		DUFFS_LOOP(
slouken@0
  1033
			RGB888_RGB555(dst, src);
slouken@0
  1034
			++src;
slouken@0
  1035
			++dst;
slouken@0
  1036
		, width);
slouken@1895
  1037
		/* *INDENT-ON* */
slouken@1895
  1038
        src += srcskip;
slouken@1895
  1039
        dst += dstskip;
slouken@1895
  1040
    }
slouken@0
  1041
#else
slouken@1895
  1042
    /* Memory align at 4-byte boundary, if necessary */
slouken@1895
  1043
    if ((long) dst & 0x03) {
slouken@1895
  1044
        /* Don't do anything if width is 0 */
slouken@1895
  1045
        if (width == 0) {
slouken@1895
  1046
            return;
slouken@1895
  1047
        }
slouken@1895
  1048
        --width;
slouken@0
  1049
slouken@1895
  1050
        while (height--) {
slouken@1895
  1051
            /* Perform copy alignment */
slouken@1895
  1052
            RGB888_RGB555(dst, src);
slouken@1895
  1053
            ++src;
slouken@1895
  1054
            ++dst;
slouken@0
  1055
slouken@1895
  1056
            /* Copy in 4 pixel chunks */
slouken@1895
  1057
            for (c = width / 4; c; --c) {
slouken@1895
  1058
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1059
                src += 2;
slouken@1895
  1060
                dst += 2;
slouken@1895
  1061
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1062
                src += 2;
slouken@1895
  1063
                dst += 2;
slouken@1895
  1064
            }
slouken@1895
  1065
            /* Get any leftovers */
slouken@1895
  1066
            switch (width & 3) {
slouken@1895
  1067
            case 3:
slouken@1895
  1068
                RGB888_RGB555(dst, src);
slouken@1895
  1069
                ++src;
slouken@1895
  1070
                ++dst;
slouken@1895
  1071
            case 2:
slouken@1895
  1072
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1073
                src += 2;
slouken@1895
  1074
                dst += 2;
slouken@1895
  1075
                break;
slouken@1895
  1076
            case 1:
slouken@1895
  1077
                RGB888_RGB555(dst, src);
slouken@1895
  1078
                ++src;
slouken@1895
  1079
                ++dst;
slouken@1895
  1080
                break;
slouken@1895
  1081
            }
slouken@1895
  1082
            src += srcskip;
slouken@1895
  1083
            dst += dstskip;
slouken@1895
  1084
        }
slouken@1895
  1085
    } else {
slouken@1895
  1086
        while (height--) {
slouken@1895
  1087
            /* Copy in 4 pixel chunks */
slouken@1895
  1088
            for (c = width / 4; c; --c) {
slouken@1895
  1089
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1090
                src += 2;
slouken@1895
  1091
                dst += 2;
slouken@1895
  1092
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1093
                src += 2;
slouken@1895
  1094
                dst += 2;
slouken@1895
  1095
            }
slouken@1895
  1096
            /* Get any leftovers */
slouken@1895
  1097
            switch (width & 3) {
slouken@1895
  1098
            case 3:
slouken@1895
  1099
                RGB888_RGB555(dst, src);
slouken@1895
  1100
                ++src;
slouken@1895
  1101
                ++dst;
slouken@1895
  1102
            case 2:
slouken@1895
  1103
                RGB888_RGB555_TWO(dst, src);
slouken@1895
  1104
                src += 2;
slouken@1895
  1105
                dst += 2;
slouken@1895
  1106
                break;
slouken@1895
  1107
            case 1:
slouken@1895
  1108
                RGB888_RGB555(dst, src);
slouken@1895
  1109
                ++src;
slouken@1895
  1110
                ++dst;
slouken@1895
  1111
                break;
slouken@1895
  1112
            }
slouken@1895
  1113
            src += srcskip;
slouken@1895
  1114
            dst += dstskip;
slouken@1895
  1115
        }
slouken@1895
  1116
    }
slouken@0
  1117
#endif /* USE_DUFFS_LOOP */
slouken@0
  1118
}
slouken@1895
  1119
slouken@0
  1120
/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */
slouken@0
  1121
#define RGB888_RGB565(dst, src) { \
slouken@1428
  1122
	*(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \
slouken@1428
  1123
	                            (((*src)&0x0000FC00)>>5)| \
slouken@1428
  1124
	                            (((*src)&0x000000F8)>>3)); \
slouken@0
  1125
}
slouken@0
  1126
#define RGB888_RGB565_TWO(dst, src) { \
slouken@0
  1127
	*(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \
slouken@0
  1128
	                     (((src[HI])&0x0000FC00)>>5)| \
slouken@0
  1129
	                     (((src[HI])&0x000000F8)>>3))<<16)| \
slouken@0
  1130
	                     (((src[LO])&0x00F80000)>>8)| \
slouken@0
  1131
	                     (((src[LO])&0x0000FC00)>>5)| \
slouken@0
  1132
	                     (((src[LO])&0x000000F8)>>3); \
slouken@0
  1133
}
slouken@1895
  1134
static void
slouken@1895
  1135
Blit_RGB888_RGB565(SDL_BlitInfo * info)
slouken@0
  1136
{
slouken@0
  1137
#ifndef USE_DUFFS_LOOP
slouken@1895
  1138
    int c;
slouken@0
  1139
#endif
slouken@1895
  1140
    int width, height;
slouken@1895
  1141
    Uint32 *src;
slouken@1895
  1142
    Uint16 *dst;
slouken@1895
  1143
    int srcskip, dstskip;
slouken@0
  1144
slouken@1895
  1145
    /* Set up some basic variables */
slouken@2262
  1146
    width = info->dst_w;
slouken@2262
  1147
    height = info->dst_h;
slouken@2262
  1148
    src = (Uint32 *) info->src;
slouken@2267
  1149
    srcskip = info->src_skip / 4;
slouken@2262
  1150
    dst = (Uint16 *) info->dst;
slouken@2267
  1151
    dstskip = info->dst_skip / 2;
slouken@0
  1152
slouken@0
  1153
#ifdef USE_DUFFS_LOOP
slouken@1895
  1154
    while (height--) {
slouken@1895
  1155
		/* *INDENT-OFF* */
slouken@0
  1156
		DUFFS_LOOP(
slouken@0
  1157
			RGB888_RGB565(dst, src);
slouken@0
  1158
			++src;
slouken@0
  1159
			++dst;
slouken@0
  1160
		, width);
slouken@1895
  1161
		/* *INDENT-ON* */
slouken@1895
  1162
        src += srcskip;
slouken@1895
  1163
        dst += dstskip;
slouken@1895
  1164
    }
slouken@0
  1165
#else
slouken@1895
  1166
    /* Memory align at 4-byte boundary, if necessary */
slouken@1895
  1167
    if ((long) dst & 0x03) {
slouken@1895
  1168
        /* Don't do anything if width is 0 */
slouken@1895
  1169
        if (width == 0) {
slouken@1895
  1170
            return;
slouken@1895
  1171
        }
slouken@1895
  1172
        --width;
slouken@0
  1173
slouken@1895
  1174
        while (height--) {
slouken@1895
  1175
            /* Perform copy alignment */
slouken@1895
  1176
            RGB888_RGB565(dst, src);
slouken@1895
  1177
            ++src;
slouken@1895
  1178
            ++dst;
slouken@0
  1179
slouken@1895
  1180
            /* Copy in 4 pixel chunks */
slouken@1895
  1181
            for (c = width / 4; c; --c) {
slouken@1895
  1182
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1183
                src += 2;
slouken@1895
  1184
                dst += 2;
slouken@1895
  1185
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1186
                src += 2;
slouken@1895
  1187
                dst += 2;
slouken@1895
  1188
            }
slouken@1895
  1189
            /* Get any leftovers */
slouken@1895
  1190
            switch (width & 3) {
slouken@1895
  1191
            case 3:
slouken@1895
  1192
                RGB888_RGB565(dst, src);
slouken@1895
  1193
                ++src;
slouken@1895
  1194
                ++dst;
slouken@1895
  1195
            case 2:
slouken@1895
  1196
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1197
                src += 2;
slouken@1895
  1198
                dst += 2;
slouken@1895
  1199
                break;
slouken@1895
  1200
            case 1:
slouken@1895
  1201
                RGB888_RGB565(dst, src);
slouken@1895
  1202
                ++src;
slouken@1895
  1203
                ++dst;
slouken@1895
  1204
                break;
slouken@1895
  1205
            }
slouken@1895
  1206
            src += srcskip;
slouken@1895
  1207
            dst += dstskip;
slouken@1895
  1208
        }
slouken@1895
  1209
    } else {
slouken@1895
  1210
        while (height--) {
slouken@1895
  1211
            /* Copy in 4 pixel chunks */
slouken@1895
  1212
            for (c = width / 4; c; --c) {
slouken@1895
  1213
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1214
                src += 2;
slouken@1895
  1215
                dst += 2;
slouken@1895
  1216
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1217
                src += 2;
slouken@1895
  1218
                dst += 2;
slouken@1895
  1219
            }
slouken@1895
  1220
            /* Get any leftovers */
slouken@1895
  1221
            switch (width & 3) {
slouken@1895
  1222
            case 3:
slouken@1895
  1223
                RGB888_RGB565(dst, src);
slouken@1895
  1224
                ++src;
slouken@1895
  1225
                ++dst;
slouken@1895
  1226
            case 2:
slouken@1895
  1227
                RGB888_RGB565_TWO(dst, src);
slouken@1895
  1228
                src += 2;
slouken@1895
  1229
                dst += 2;
slouken@1895
  1230
                break;
slouken@1895
  1231
            case 1:
slouken@1895
  1232
                RGB888_RGB565(dst, src);
slouken@1895
  1233
                ++src;
slouken@1895
  1234
                ++dst;
slouken@1895
  1235
                break;
slouken@1895
  1236
            }
slouken@1895
  1237
            src += srcskip;
slouken@1895
  1238
            dst += dstskip;
slouken@1895
  1239
        }
slouken@1895
  1240
    }
slouken@0
  1241
#endif /* USE_DUFFS_LOOP */
slouken@0
  1242
}
slouken@0
  1243
slouken@0
  1244
slouken@0
  1245
/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
icculus@1047
  1246
#define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
slouken@1895
  1247
static void
slouken@1895
  1248
Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map)
slouken@0
  1249
{
slouken@0
  1250
#ifndef USE_DUFFS_LOOP
slouken@1895
  1251
    int c;
slouken@0
  1252
#endif
slouken@1895
  1253
    int width, height;
slouken@1895
  1254
    Uint8 *src;
slouken@1895
  1255
    Uint32 *dst;
slouken@1895
  1256
    int srcskip, dstskip;
slouken@0
  1257
slouken@1895
  1258
    /* Set up some basic variables */
slouken@2262
  1259
    width = info->dst_w;
slouken@2262
  1260
    height = info->dst_h;
slouken@2262
  1261
    src = (Uint8 *) info->src;
slouken@2267
  1262
    srcskip = info->src_skip;
slouken@2262
  1263
    dst = (Uint32 *) info->dst;
slouken@2267
  1264
    dstskip = info->dst_skip / 4;
slouken@0
  1265
slouken@0
  1266
#ifdef USE_DUFFS_LOOP
slouken@1895
  1267
    while (height--) {
slouken@1895
  1268
		/* *INDENT-OFF* */
slouken@0
  1269
		DUFFS_LOOP(
slouken@0
  1270
		{
slouken@0
  1271
			*dst++ = RGB565_32(dst, src, map);
slouken@0
  1272
			src += 2;
slouken@0
  1273
		},
slouken@0
  1274
		width);
slouken@1895
  1275
		/* *INDENT-ON* */
slouken@1895
  1276
        src += srcskip;
slouken@1895
  1277
        dst += dstskip;
slouken@1895
  1278
    }
slouken@0
  1279
#else
slouken@1895
  1280
    while (height--) {
slouken@1895
  1281
        /* Copy in 4 pixel chunks */
slouken@1895
  1282
        for (c = width / 4; c; --c) {
slouken@1895
  1283
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1284
            src += 2;
slouken@1895
  1285
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1286
            src += 2;
slouken@1895
  1287
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1288
            src += 2;
slouken@1895
  1289
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1290
            src += 2;
slouken@1895
  1291
        }
slouken@1895
  1292
        /* Get any leftovers */
slouken@1895
  1293
        switch (width & 3) {
slouken@1895
  1294
        case 3:
slouken@1895
  1295
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1296
            src += 2;
slouken@1895
  1297
        case 2:
slouken@1895
  1298
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1299
            src += 2;
slouken@1895
  1300
        case 1:
slouken@1895
  1301
            *dst++ = RGB565_32(dst, src, map);
slouken@1895
  1302
            src += 2;
slouken@1895
  1303
            break;
slouken@1895
  1304
        }
slouken@1895
  1305
        src += srcskip;
slouken@1895
  1306
        dst += dstskip;
slouken@1895
  1307
    }
slouken@0
  1308
#endif /* USE_DUFFS_LOOP */
slouken@0
  1309
}
slouken@0
  1310
slouken@0
  1311
/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
slouken@91
  1312
static const Uint32 RGB565_ARGB8888_LUT[512] = {
slouken@1895
  1313
    0x00000000, 0xff000000, 0x00000008, 0xff002000,
slouken@1895
  1314
    0x00000010, 0xff004000, 0x00000018, 0xff006100,
slouken@1895
  1315
    0x00000020, 0xff008100, 0x00000029, 0xff00a100,
slouken@1895
  1316
    0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
slouken@1895
  1317
    0x00000041, 0xff080000, 0x0000004a, 0xff082000,
slouken@1895
  1318
    0x00000052, 0xff084000, 0x0000005a, 0xff086100,
slouken@1895
  1319
    0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
slouken@1895
  1320
    0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
slouken@1895
  1321
    0x00000083, 0xff100000, 0x0000008b, 0xff102000,
slouken@1895
  1322
    0x00000094, 0xff104000, 0x0000009c, 0xff106100,
slouken@1895
  1323
    0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
slouken@1895
  1324
    0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
slouken@1895
  1325
    0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
slouken@1895
  1326
    0x000000d5, 0xff184000, 0x000000de, 0xff186100,
slouken@1895
  1327
    0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
slouken@1895
  1328
    0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
slouken@1895
  1329
    0x00000400, 0xff200000, 0x00000408, 0xff202000,
slouken@1895
  1330
    0x00000410, 0xff204000, 0x00000418, 0xff206100,
slouken@1895
  1331
    0x00000420, 0xff208100, 0x00000429, 0xff20a100,
slouken@1895
  1332
    0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
slouken@1895
  1333
    0x00000441, 0xff290000, 0x0000044a, 0xff292000,
slouken@1895
  1334
    0x00000452, 0xff294000, 0x0000045a, 0xff296100,
slouken@1895
  1335
    0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
slouken@1895
  1336
    0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
slouken@1895
  1337
    0x00000483, 0xff310000, 0x0000048b, 0xff312000,
slouken@1895
  1338
    0x00000494, 0xff314000, 0x0000049c, 0xff316100,
slouken@1895
  1339
    0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
slouken@1895
  1340
    0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
slouken@1895
  1341
    0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
slouken@1895
  1342
    0x000004d5, 0xff394000, 0x000004de, 0xff396100,
slouken@1895
  1343
    0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
slouken@1895
  1344
    0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
slouken@1895
  1345
    0x00000800, 0xff410000, 0x00000808, 0xff412000,
slouken@1895
  1346
    0x00000810, 0xff414000, 0x00000818, 0xff416100,
slouken@1895
  1347
    0x00000820, 0xff418100, 0x00000829, 0xff41a100,
slouken@1895
  1348
    0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
slouken@1895
  1349
    0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
slouken@1895
  1350
    0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
slouken@1895
  1351
    0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
slouken@1895
  1352
    0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
slouken@1895
  1353
    0x00000883, 0xff520000, 0x0000088b, 0xff522000,
slouken@1895
  1354
    0x00000894, 0xff524000, 0x0000089c, 0xff526100,
slouken@1895
  1355
    0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
slouken@1895
  1356
    0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
slouken@1895
  1357
    0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
slouken@1895
  1358
    0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
slouken@1895
  1359
    0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
slouken@1895
  1360
    0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
slouken@1895
  1361
    0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
slouken@1895
  1362
    0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
slouken@1895
  1363
    0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
slouken@1895
  1364
    0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
slouken@1895
  1365
    0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
slouken@1895
  1366
    0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
slouken@1895
  1367
    0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
slouken@1895
  1368
    0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
slouken@1895
  1369
    0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
slouken@1895
  1370
    0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
slouken@1895
  1371
    0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
slouken@1895
  1372
    0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
slouken@1895
  1373
    0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
slouken@1895
  1374
    0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
slouken@1895
  1375
    0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
slouken@1895
  1376
    0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
slouken@1895
  1377
    0x00001000, 0xff830000, 0x00001008, 0xff832000,
slouken@1895
  1378
    0x00001010, 0xff834000, 0x00001018, 0xff836100,
slouken@1895
  1379
    0x00001020, 0xff838100, 0x00001029, 0xff83a100,
slouken@1895
  1380
    0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
slouken@1895
  1381
    0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
slouken@1895
  1382
    0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
slouken@1895
  1383
    0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
slouken@1895
  1384
    0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
slouken@1895
  1385
    0x00001083, 0xff940000, 0x0000108b, 0xff942000,
slouken@1895
  1386
    0x00001094, 0xff944000, 0x0000109c, 0xff946100,
slouken@1895
  1387
    0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
slouken@1895
  1388
    0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
slouken@1895
  1389
    0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
slouken@1895
  1390
    0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
slouken@1895
  1391
    0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
slouken@1895
  1392
    0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
slouken@1895
  1393
    0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
slouken@1895
  1394
    0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
slouken@1895
  1395
    0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
slouken@1895
  1396
    0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
slouken@1895
  1397
    0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
slouken@1895
  1398
    0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
slouken@1895
  1399
    0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
slouken@1895
  1400
    0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
slouken@1895
  1401
    0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
slouken@1895
  1402
    0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
slouken@1895
  1403
    0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
slouken@1895
  1404
    0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
slouken@1895
  1405
    0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
slouken@1895
  1406
    0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
slouken@1895
  1407
    0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
slouken@1895
  1408
    0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
slouken@1895
  1409
    0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
slouken@1895
  1410
    0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
slouken@1895
  1411
    0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
slouken@1895
  1412
    0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
slouken@1895
  1413
    0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
slouken@1895
  1414
    0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
slouken@1895
  1415
    0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
slouken@1895
  1416
    0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
slouken@1895
  1417
    0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
slouken@1895
  1418
    0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
slouken@1895
  1419
    0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
slouken@1895
  1420
    0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
slouken@1895
  1421
    0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
slouken@1895
  1422
    0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
slouken@1895
  1423
    0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
slouken@1895
  1424
    0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
slouken@1895
  1425
    0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
slouken@1895
  1426
    0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
slouken@1895
  1427
    0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
slouken@1895
  1428
    0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
slouken@1895
  1429
    0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
slouken@1895
  1430
    0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
slouken@1895
  1431
    0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
slouken@1895
  1432
    0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
slouken@1895
  1433
    0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
slouken@1895
  1434
    0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
slouken@1895
  1435
    0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
slouken@1895
  1436
    0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
slouken@1895
  1437
    0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
slouken@1895
  1438
    0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
slouken@1895
  1439
    0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
slouken@1895
  1440
    0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
slouken@0
  1441
};
slouken@2735
  1442
slouken@1895
  1443
static void
slouken@1895
  1444
Blit_RGB565_ARGB8888(SDL_BlitInfo * info)
slouken@0
  1445
{
slouken@0
  1446
    Blit_RGB565_32(info, RGB565_ARGB8888_LUT);
slouken@0
  1447
}
slouken@0
  1448
slouken@0
  1449
/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */
slouken@91
  1450
static const Uint32 RGB565_ABGR8888_LUT[512] = {
slouken@1895
  1451
    0xff000000, 0x00000000, 0xff080000, 0x00002000,
slouken@1895
  1452
    0xff100000, 0x00004000, 0xff180000, 0x00006100,
slouken@1895
  1453
    0xff200000, 0x00008100, 0xff290000, 0x0000a100,
slouken@1895
  1454
    0xff310000, 0x0000c200, 0xff390000, 0x0000e200,
slouken@1895
  1455
    0xff410000, 0x00000008, 0xff4a0000, 0x00002008,
slouken@1895
  1456
    0xff520000, 0x00004008, 0xff5a0000, 0x00006108,
slouken@1895
  1457
    0xff620000, 0x00008108, 0xff6a0000, 0x0000a108,
slouken@1895
  1458
    0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208,
slouken@1895
  1459
    0xff830000, 0x00000010, 0xff8b0000, 0x00002010,
slouken@1895
  1460
    0xff940000, 0x00004010, 0xff9c0000, 0x00006110,
slouken@1895
  1461
    0xffa40000, 0x00008110, 0xffac0000, 0x0000a110,
slouken@1895
  1462
    0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210,
slouken@1895
  1463
    0xffc50000, 0x00000018, 0xffcd0000, 0x00002018,
slouken@1895
  1464
    0xffd50000, 0x00004018, 0xffde0000, 0x00006118,
slouken@1895
  1465
    0xffe60000, 0x00008118, 0xffee0000, 0x0000a118,
slouken@1895
  1466
    0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218,
slouken@1895
  1467
    0xff000400, 0x00000020, 0xff080400, 0x00002020,
slouken@1895
  1468
    0xff100400, 0x00004020, 0xff180400, 0x00006120,
slouken@1895
  1469
    0xff200400, 0x00008120, 0xff290400, 0x0000a120,
slouken@1895
  1470
    0xff310400, 0x0000c220, 0xff390400, 0x0000e220,
slouken@1895
  1471
    0xff410400, 0x00000029, 0xff4a0400, 0x00002029,
slouken@1895
  1472
    0xff520400, 0x00004029, 0xff5a0400, 0x00006129,
slouken@1895
  1473
    0xff620400, 0x00008129, 0xff6a0400, 0x0000a129,
slouken@1895
  1474
    0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229,
slouken@1895
  1475
    0xff830400, 0x00000031, 0xff8b0400, 0x00002031,
slouken@1895
  1476
    0xff940400, 0x00004031, 0xff9c0400, 0x00006131,
slouken@1895
  1477
    0xffa40400, 0x00008131, 0xffac0400, 0x0000a131,
slouken@1895
  1478
    0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231,
slouken@1895
  1479
    0xffc50400, 0x00000039, 0xffcd0400, 0x00002039,
slouken@1895
  1480
    0xffd50400, 0x00004039, 0xffde0400, 0x00006139,
slouken@1895
  1481
    0xffe60400, 0x00008139, 0xffee0400, 0x0000a139,
slouken@1895
  1482
    0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239,
slouken@1895
  1483
    0xff000800, 0x00000041, 0xff080800, 0x00002041,
slouken@1895
  1484
    0xff100800, 0x00004041, 0xff180800, 0x00006141,
slouken@1895
  1485
    0xff200800, 0x00008141, 0xff290800, 0x0000a141,
slouken@1895
  1486
    0xff310800, 0x0000c241, 0xff390800, 0x0000e241,
slouken@1895
  1487
    0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a,
slouken@1895
  1488
    0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a,
slouken@1895
  1489
    0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a,
slouken@1895
  1490
    0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a,
slouken@1895
  1491
    0xff830800, 0x00000052, 0xff8b0800, 0x00002052,
slouken@1895
  1492
    0xff940800, 0x00004052, 0xff9c0800, 0x00006152,
slouken@1895
  1493
    0xffa40800, 0x00008152, 0xffac0800, 0x0000a152,
slouken@1895
  1494
    0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252,
slouken@1895
  1495
    0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a,
slouken@1895
  1496
    0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a,
slouken@1895
  1497
    0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a,
slouken@1895
  1498
    0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a,
slouken@1895
  1499
    0xff000c00, 0x00000062, 0xff080c00, 0x00002062,
slouken@1895
  1500
    0xff100c00, 0x00004062, 0xff180c00, 0x00006162,
slouken@1895
  1501
    0xff200c00, 0x00008162, 0xff290c00, 0x0000a162,
slouken@1895
  1502
    0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262,
slouken@1895
  1503
    0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a,
slouken@1895
  1504
    0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a,
slouken@1895
  1505
    0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a,
slouken@1895
  1506
    0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a,
slouken@1895
  1507
    0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073,
slouken@1895
  1508
    0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173,
slouken@1895
  1509
    0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173,
slouken@1895
  1510
    0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273,
slouken@1895
  1511
    0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b,
slouken@1895
  1512
    0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b,
slouken@1895
  1513
    0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b,
slouken@1895
  1514
    0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b,
slouken@1895
  1515
    0xff001000, 0x00000083, 0xff081000, 0x00002083,
slouken@1895
  1516
    0xff101000, 0x00004083, 0xff181000, 0x00006183,
slouken@1895
  1517
    0xff201000, 0x00008183, 0xff291000, 0x0000a183,
slouken@1895
  1518
    0xff311000, 0x0000c283, 0xff391000, 0x0000e283,
slouken@1895
  1519
    0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b,
slouken@1895
  1520
    0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b,
slouken@1895
  1521
    0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b,
slouken@1895
  1522
    0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b,
slouken@1895
  1523
    0xff831000, 0x00000094, 0xff8b1000, 0x00002094,
slouken@1895
  1524
    0xff941000, 0x00004094, 0xff9c1000, 0x00006194,
slouken@1895
  1525
    0xffa41000, 0x00008194, 0xffac1000, 0x0000a194,
slouken@1895
  1526
    0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294,
slouken@1895
  1527
    0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c,
slouken@1895
  1528
    0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c,
slouken@1895
  1529
    0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c,
slouken@1895
  1530
    0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c,
slouken@1895
  1531
    0xff001400, 0x000000a4, 0xff081400, 0x000020a4,
slouken@1895
  1532
    0xff101400, 0x000040a4, 0xff181400, 0x000061a4,
slouken@1895
  1533
    0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4,
slouken@1895
  1534
    0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4,
slouken@1895
  1535
    0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac,
slouken@1895
  1536
    0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac,
slouken@1895
  1537
    0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac,
slouken@1895
  1538
    0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac,
slouken@1895
  1539
    0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4,
slouken@1895
  1540
    0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4,
slouken@1895
  1541
    0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4,
slouken@1895
  1542
    0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4,
slouken@1895
  1543
    0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd,
slouken@1895
  1544
    0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd,
slouken@1895
  1545
    0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd,
slouken@1895
  1546
    0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd,
slouken@1895
  1547
    0xff001800, 0x000000c5, 0xff081800, 0x000020c5,
slouken@1895
  1548
    0xff101800, 0x000040c5, 0xff181800, 0x000061c5,
slouken@1895
  1549
    0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5,
slouken@1895
  1550
    0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5,
slouken@1895
  1551
    0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd,
slouken@1895
  1552
    0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd,
slouken@1895
  1553
    0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd,
slouken@1895
  1554
    0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd,
slouken@1895
  1555
    0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5,
slouken@1895
  1556
    0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5,
slouken@1895
  1557
    0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5,
slouken@1895
  1558
    0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5,
slouken@1895
  1559
    0xffc51800, 0x000000de, 0xffcd1800, 0x000020de,
slouken@1895
  1560
    0xffd51800, 0x000040de, 0xffde1800, 0x000061de,
slouken@1895
  1561
    0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de,
slouken@1895
  1562
    0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de,
slouken@1895
  1563
    0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6,
slouken@1895
  1564
    0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6,
slouken@1895
  1565
    0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6,
slouken@1895
  1566
    0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6,
slouken@1895
  1567
    0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee,
slouken@1895
  1568
    0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee,
slouken@1895
  1569
    0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee,
slouken@1895
  1570
    0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee,
slouken@1895
  1571
    0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6,
slouken@1895
  1572
    0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6,
slouken@1895
  1573
    0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6,
slouken@1895
  1574
    0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6,
slouken@1895
  1575
    0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff,
slouken@1895
  1576
    0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff,
slouken@1895
  1577
    0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff,
slouken@1895
  1578
    0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff
slouken@0
  1579
};
slouken@2735
  1580
slouken@1895
  1581
static void
slouken@1895
  1582
Blit_RGB565_ABGR8888(SDL_BlitInfo * info)
slouken@0
  1583
{
slouken@0
  1584
    Blit_RGB565_32(info, RGB565_ABGR8888_LUT);
slouken@0
  1585
}
slouken@0
  1586
slouken@0
  1587
/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
slouken@91
  1588
static const Uint32 RGB565_RGBA8888_LUT[512] = {
slouken@1895
  1589
    0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
slouken@1895
  1590
    0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
slouken@1895
  1591
    0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
slouken@1895
  1592
    0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
slouken@1895
  1593
    0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
slouken@1895
  1594
    0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
slouken@1895
  1595
    0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
slouken@1895
  1596
    0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
slouken@1895
  1597
    0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
slouken@1895
  1598
    0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
slouken@1895
  1599
    0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
slouken@1895
  1600
    0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
slouken@1895
  1601
    0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
slouken@1895
  1602
    0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
slouken@1895
  1603
    0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
slouken@1895
  1604
    0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
slouken@1895
  1605
    0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
slouken@1895
  1606
    0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
slouken@1895
  1607
    0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
slouken@1895
  1608
    0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
slouken@1895
  1609
    0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
slouken@1895
  1610
    0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
slouken@1895
  1611
    0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
slouken@1895
  1612
    0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
slouken@1895
  1613
    0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
slouken@1895
  1614
    0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
slouken@1895
  1615
    0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
slouken@1895
  1616
    0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
slouken@1895
  1617
    0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
slouken@1895
  1618
    0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
slouken@1895
  1619
    0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
slouken@1895
  1620
    0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
slouken@1895
  1621
    0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
slouken@1895
  1622
    0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
slouken@1895
  1623
    0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
slouken@1895
  1624
    0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
slouken@1895
  1625
    0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
slouken@1895
  1626
    0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
slouken@1895
  1627
    0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
slouken@1895
  1628
    0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
slouken@1895
  1629
    0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
slouken@1895
  1630
    0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
slouken@1895
  1631
    0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
slouken@1895
  1632
    0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
slouken@1895
  1633
    0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
slouken@1895
  1634
    0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
slouken@1895
  1635
    0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
slouken@1895
  1636
    0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
slouken@1895
  1637
    0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
slouken@1895
  1638
    0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
slouken@1895
  1639
    0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
slouken@1895
  1640
    0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
slouken@1895
  1641
    0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
slouken@1895
  1642
    0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
slouken@1895
  1643
    0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
slouken@1895
  1644
    0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
slouken@1895
  1645
    0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
slouken@1895
  1646
    0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
slouken@1895
  1647
    0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
slouken@1895
  1648
    0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
slouken@1895
  1649
    0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
slouken@1895
  1650
    0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
slouken@1895
  1651
    0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
slouken@1895
  1652
    0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
slouken@1895
  1653
    0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
slouken@1895
  1654
    0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
slouken@1895
  1655
    0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
slouken@1895
  1656
    0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
slouken@1895
  1657
    0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
slouken@1895
  1658
    0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
slouken@1895
  1659
    0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
slouken@1895
  1660
    0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
slouken@1895
  1661
    0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
slouken@1895
  1662
    0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
slouken@1895
  1663
    0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
slouken@1895
  1664
    0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
slouken@1895
  1665
    0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
slouken@1895
  1666
    0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
slouken@1895
  1667
    0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
slouken@1895
  1668
    0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
slouken@1895
  1669
    0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
slouken@1895
  1670
    0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
slouken@1895
  1671
    0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
slouken@1895
  1672
    0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
slouken@1895
  1673
    0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
slouken@1895
  1674
    0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
slouken@1895
  1675
    0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
slouken@1895
  1676
    0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
slouken@1895
  1677
    0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
slouken@1895
  1678
    0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
slouken@1895
  1679
    0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
slouken@1895
  1680
    0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
slouken@1895
  1681
    0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
slouken@1895
  1682
    0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
slouken@1895
  1683
    0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
slouken@1895
  1684
    0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
slouken@1895
  1685
    0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
slouken@1895
  1686
    0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
slouken@1895
  1687
    0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
slouken@1895
  1688
    0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
slouken@1895
  1689
    0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
slouken@1895
  1690
    0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
slouken@1895
  1691
    0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
slouken@1895
  1692
    0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
slouken@1895
  1693
    0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
slouken@1895
  1694
    0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
slouken@1895
  1695
    0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
slouken@1895
  1696
    0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
slouken@1895
  1697
    0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
slouken@1895
  1698
    0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
slouken@1895
  1699
    0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
slouken@1895
  1700
    0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
slouken@1895
  1701
    0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
slouken@1895
  1702
    0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
slouken@1895
  1703
    0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
slouken@1895
  1704
    0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
slouken@1895
  1705
    0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
slouken@1895
  1706
    0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
slouken@1895
  1707
    0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
slouken@1895
  1708
    0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
slouken@1895
  1709
    0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
slouken@1895
  1710
    0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
slouken@1895
  1711
    0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
slouken@1895
  1712
    0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
slouken@1895
  1713
    0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
slouken@1895
  1714
    0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
slouken@1895
  1715
    0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
slouken@1895
  1716
    0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
slouken@0
  1717
};
slouken@2735
  1718
slouken@1895
  1719
static void
slouken@1895
  1720
Blit_RGB565_RGBA8888(SDL_BlitInfo * info)
slouken@0
  1721
{
slouken@0
  1722
    Blit_RGB565_32(info, RGB565_RGBA8888_LUT);
slouken@0
  1723
}
slouken@0
  1724
slouken@0
  1725
/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */
slouken@91
  1726
static const Uint32 RGB565_BGRA8888_LUT[512] = {
slouken@1895
  1727
    0x00000000, 0x000000ff, 0x08000000, 0x002000ff,
slouken@1895
  1728
    0x10000000, 0x004000ff, 0x18000000, 0x006100ff,
slouken@1895
  1729
    0x20000000, 0x008100ff, 0x29000000, 0x00a100ff,
slouken@1895
  1730
    0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff,
slouken@1895
  1731
    0x41000000, 0x000008ff, 0x4a000000, 0x002008ff,
slouken@1895
  1732
    0x52000000, 0x004008ff, 0x5a000000, 0x006108ff,
slouken@1895
  1733
    0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff,
slouken@1895
  1734
    0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff,
slouken@1895
  1735
    0x83000000, 0x000010ff, 0x8b000000, 0x002010ff,
slouken@1895
  1736
    0x94000000, 0x004010ff, 0x9c000000, 0x006110ff,
slouken@1895
  1737
    0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff,
slouken@1895
  1738
    0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff,
slouken@1895
  1739
    0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff,
slouken@1895
  1740
    0xd5000000, 0x004018ff, 0xde000000, 0x006118ff,
slouken@1895
  1741
    0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff,
slouken@1895
  1742
    0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff,
slouken@1895
  1743
    0x00040000, 0x000020ff, 0x08040000, 0x002020ff,
slouken@1895
  1744
    0x10040000, 0x004020ff, 0x18040000, 0x006120ff,
slouken@1895
  1745
    0x20040000, 0x008120ff, 0x29040000, 0x00a120ff,
slouken@1895
  1746
    0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff,
slouken@1895
  1747
    0x41040000, 0x000029ff, 0x4a040000, 0x002029ff,
slouken@1895
  1748
    0x52040000, 0x004029ff, 0x5a040000, 0x006129ff,
slouken@1895
  1749
    0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff,
slouken@1895
  1750
    0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff,
slouken@1895
  1751
    0x83040000, 0x000031ff, 0x8b040000, 0x002031ff,
slouken@1895
  1752
    0x94040000, 0x004031ff, 0x9c040000, 0x006131ff,
slouken@1895
  1753
    0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff,
slouken@1895
  1754
    0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff,
slouken@1895
  1755
    0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff,
slouken@1895
  1756
    0xd5040000, 0x004039ff, 0xde040000, 0x006139ff,
slouken@1895
  1757
    0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff,
slouken@1895
  1758
    0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff,
slouken@1895
  1759
    0x00080000, 0x000041ff, 0x08080000, 0x002041ff,
slouken@1895
  1760
    0x10080000, 0x004041ff, 0x18080000, 0x006141ff,
slouken@1895
  1761
    0x20080000, 0x008141ff, 0x29080000, 0x00a141ff,
slouken@1895
  1762
    0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff,
slouken@1895
  1763
    0x41080000, 0x00004aff, 0x4a080000, 0x00204aff,
slouken@1895
  1764
    0x52080000, 0x00404aff, 0x5a080000, 0x00614aff,
slouken@1895
  1765
    0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff,
slouken@1895
  1766
    0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff,
slouken@1895
  1767
    0x83080000, 0x000052ff, 0x8b080000, 0x002052ff,
slouken@1895
  1768
    0x94080000, 0x004052ff, 0x9c080000, 0x006152ff,
slouken@1895
  1769
    0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff,
slouken@1895
  1770
    0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff,
slouken@1895
  1771
    0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff,
slouken@1895
  1772
    0xd5080000, 0x00405aff, 0xde080000, 0x00615aff,
slouken@1895
  1773
    0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff,
slouken@1895
  1774
    0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff,
slouken@1895
  1775
    0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff,
slouken@1895
  1776
    0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff,
slouken@1895
  1777
    0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff,
slouken@1895
  1778
    0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff,
slouken@1895
  1779
    0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff,
slouken@1895
  1780
    0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff,
slouken@1895
  1781
    0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff,
slouken@1895
  1782
    0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff,
slouken@1895
  1783
    0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff,
slouken@1895
  1784
    0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff,
slouken@1895
  1785
    0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff,
slouken@1895
  1786
    0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff,
slouken@1895
  1787
    0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff,
slouken@1895
  1788
    0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff,
slouken@1895
  1789
    0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff,
slouken@1895
  1790
    0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff,
slouken@1895
  1791
    0x00100000, 0x000083ff, 0x08100000, 0x002083ff,
slouken@1895
  1792
    0x10100000, 0x004083ff, 0x18100000, 0x006183ff,
slouken@1895
  1793
    0x20100000, 0x008183ff, 0x29100000, 0x00a183ff,
slouken@1895
  1794
    0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff,
slouken@1895
  1795
    0x41100000, 0x00008bff, 0x4a100000, 0x00208bff,
slouken@1895
  1796
    0x52100000, 0x00408bff, 0x5a100000, 0x00618bff,
slouken@1895
  1797
    0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff,
slouken@1895
  1798
    0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff,
slouken@1895
  1799
    0x83100000, 0x000094ff, 0x8b100000, 0x002094ff,
slouken@1895
  1800
    0x94100000, 0x004094ff, 0x9c100000, 0x006194ff,
slouken@1895
  1801
    0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff,
slouken@1895
  1802
    0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff,
slouken@1895
  1803
    0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff,
slouken@1895
  1804
    0xd5100000, 0x00409cff, 0xde100000, 0x00619cff,
slouken@1895
  1805
    0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff,
slouken@1895
  1806
    0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff,
slouken@1895
  1807
    0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff,
slouken@1895
  1808
    0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff,
slouken@1895
  1809
    0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff,
slouken@1895
  1810
    0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff,
slouken@1895
  1811
    0x41140000, 0x0000acff, 0x4a140000, 0x0020acff,
slouken@1895
  1812
    0x52140000, 0x0040acff, 0x5a140000, 0x0061acff,
slouken@1895
  1813
    0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff,
slouken@1895
  1814
    0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff,
slouken@1895
  1815
    0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff,
slouken@1895
  1816
    0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff,
slouken@1895
  1817
    0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff,
slouken@1895
  1818
    0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff,
slouken@1895
  1819
    0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff,
slouken@1895
  1820
    0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff,
slouken@1895
  1821
    0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff,
slouken@1895
  1822
    0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff,
slouken@1895
  1823
    0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff,
slouken@1895
  1824
    0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff,
slouken@1895
  1825
    0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff,
slouken@1895
  1826
    0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff,
slouken@1895
  1827
    0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff,
slouken@1895
  1828
    0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff,
slouken@1895
  1829
    0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff,
slouken@1895
  1830
    0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff,
slouken@1895
  1831
    0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff,
slouken@1895
  1832
    0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff,
slouken@1895
  1833
    0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff,
slouken@1895
  1834
    0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff,
slouken@1895
  1835
    0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff,
slouken@1895
  1836
    0xd5180000, 0x0040deff, 0xde180000, 0x0061deff,
slouken@1895
  1837
    0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff,
slouken@1895
  1838
    0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff,
slouken@1895
  1839
    0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff,
slouken@1895
  1840
    0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff,
slouken@1895
  1841
    0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff,
slouken@1895
  1842
    0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff,
slouken@1895
  1843
    0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff,
slouken@1895
  1844
    0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff,
slouken@1895
  1845
    0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff,
slouken@1895
  1846
    0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff,
slouken@1895
  1847
    0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff,
slouken@1895
  1848
    0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff,
slouken@1895
  1849
    0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff,
slouken@1895
  1850
    0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff,
slouken@1895
  1851
    0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff,
slouken@1895
  1852
    0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff,
slouken@1895
  1853
    0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff,
slouken@1895
  1854
    0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff
slouken@0
  1855
};
slouken@2735
  1856
slouken@1895
  1857
static void
slouken@1895
  1858
Blit_RGB565_BGRA8888(SDL_BlitInfo * info)
slouken@0
  1859
{
slouken@0
  1860
    Blit_RGB565_32(info, RGB565_BGRA8888_LUT);
slouken@0
  1861
}
slouken@0
  1862
slouken@0
  1863
/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */
slouken@0
  1864
#ifndef RGB888_RGB332
slouken@0
  1865
#define RGB888_RGB332(dst, src) { \
slouken@0
  1866
	dst = (((src)&0x00E00000)>>16)| \
slouken@0
  1867
	      (((src)&0x0000E000)>>11)| \
slouken@0
  1868
	      (((src)&0x000000C0)>>6); \
slouken@0
  1869
}
slouken@0
  1870
#endif
slouken@1895
  1871
static void
slouken@1895
  1872
Blit_RGB888_index8_map(SDL_BlitInfo * info)
slouken@0
  1873
{
slouken@0
  1874
#ifndef USE_DUFFS_LOOP
slouken@1895
  1875
    int c;
slouken@0
  1876
#endif
slouken@1895
  1877
    int Pixel;
slouken@1895
  1878
    int width, height;
slouken@1895
  1879
    Uint32 *src;
slouken@1895
  1880
    const Uint8 *map;
slouken@1895
  1881
    Uint8 *dst;
slouken@1895
  1882
    int srcskip, dstskip;
slouken@0
  1883
slouken@1895
  1884
    /* Set up some basic variables */
slouken@2262
  1885
    width = info->dst_w;
slouken@2262
  1886
    height = info->dst_h;
slouken@2262
  1887
    src = (Uint32 *) info->src;
slouken@2267
  1888
    srcskip = info->src_skip / 4;
slouken@2262
  1889
    dst = info->dst;
slouken@2267
  1890
    dstskip = info->dst_skip;
slouken@1895
  1891
    map = info->table;
slouken@0
  1892
slouken@0
  1893
#ifdef USE_DUFFS_LOOP
slouken@1895
  1894
    while (height--) {
slouken@1895
  1895
		/* *INDENT-OFF* */
slouken@0
  1896
		DUFFS_LOOP(
icculus@1162
  1897
			RGB888_RGB332(Pixel, *src);
icculus@1162
  1898
			*dst++ = map[Pixel];
slouken@0
  1899
			++src;
slouken@0
  1900
		, width);
slouken@1895
  1901
		/* *INDENT-ON* */
slouken@1895
  1902
        src += srcskip;
slouken@1895
  1903
        dst += dstskip;
slouken@1895
  1904
    }
slouken@0
  1905
#else
slouken@1895
  1906
    while (height--) {
slouken@1895
  1907
        for (c = width / 4; c; --c) {
slouken@1895
  1908
            /* Pack RGB into 8bit pixel */
slouken@1895
  1909
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1910
            *dst++ = map[Pixel];
slouken@1895
  1911
            ++src;
slouken@1895
  1912
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1913
            *dst++ = map[Pixel];
slouken@1895
  1914
            ++src;
slouken@1895
  1915
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1916
            *dst++ = map[Pixel];
slouken@1895
  1917
            ++src;
slouken@1895
  1918
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1919
            *dst++ = map[Pixel];
slouken@1895
  1920
            ++src;
slouken@1895
  1921
        }
slouken@1895
  1922
        switch (width & 3) {
slouken@1895
  1923
        case 3:
slouken@1895
  1924
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1925
            *dst++ = map[Pixel];
slouken@1895
  1926
            ++src;
slouken@1895
  1927
        case 2:
slouken@1895
  1928
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1929
            *dst++ = map[Pixel];
slouken@1895
  1930
            ++src;
slouken@1895
  1931
        case 1:
slouken@1895
  1932
            RGB888_RGB332(Pixel, *src);
slouken@1895
  1933
            *dst++ = map[Pixel];
slouken@1895
  1934
            ++src;
slouken@1895
  1935
        }
slouken@1895
  1936
        src += srcskip;
slouken@1895
  1937
        dst += dstskip;
slouken@1895
  1938
    }
slouken@0
  1939
#endif /* USE_DUFFS_LOOP */
slouken@0
  1940
}
slouken@2735
  1941
slouken@1895
  1942
static void
slouken@1895
  1943
BlitNto1(SDL_BlitInfo * info)
slouken@0
  1944
{
slouken@0
  1945
#ifndef USE_DUFFS_LOOP
slouken@1895
  1946
    int c;
slouken@0
  1947
#endif
slouken@1895
  1948
    int width, height;
slouken@1895
  1949
    Uint8 *src;
slouken@1895
  1950
    const Uint8 *map;
slouken@1895
  1951
    Uint8 *dst;
slouken@1895
  1952
    int srcskip, dstskip;
slouken@1895
  1953
    int srcbpp;
slouken@1895
  1954
    Uint32 Pixel;
slouken@1895
  1955
    int sR, sG, sB;
slouken@1895
  1956
    SDL_PixelFormat *srcfmt;
slouken@0
  1957
slouken@1895
  1958
    /* Set up some basic variables */
slouken@2262
  1959
    width = info->dst_w;
slouken@2262
  1960
    height = info->dst_h;
slouken@2262
  1961
    src = info->src;
slouken@2267
  1962
    srcskip = info->src_skip;
slouken@2262
  1963
    dst = info->dst;
slouken@2267
  1964
    dstskip = info->dst_skip;
slouken@1895
  1965
    map = info->table;
slouken@2267
  1966
    srcfmt = info->src_fmt;
slouken@1895
  1967
    srcbpp = srcfmt->BytesPerPixel;
slouken@0
  1968
slouken@1895
  1969
    if (map == NULL) {
slouken@1895
  1970
        while (height--) {
slouken@0
  1971
#ifdef USE_DUFFS_LOOP
slouken@1895
  1972
			/* *INDENT-OFF* */
slouken@0
  1973
			DUFFS_LOOP(
icculus@1162
  1974
				DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
slouken@0
  1975
								sR, sG, sB);
slouken@0
  1976
				if ( 1 ) {
slouken@0
  1977
				  	/* Pack RGB into 8bit pixel */
slouken@0
  1978
				  	*dst = ((sR>>5)<<(3+2))|
slouken@0
  1979
					        ((sG>>5)<<(2)) |
slouken@0
  1980
					        ((sB>>6)<<(0)) ;
slouken@0
  1981
				}
slouken@0
  1982
				dst++;
slouken@0
  1983
				src += srcbpp;
slouken@0
  1984
			, width);
slouken@1895
  1985
			/* *INDENT-ON* */
slouken@0
  1986
#else
slouken@1895
  1987
            for (c = width; c; --c) {
slouken@1895
  1988
                DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
slouken@1895
  1989
                if (1) {
slouken@1895
  1990
                    /* Pack RGB into 8bit pixel */
slouken@1895
  1991
                    *dst = ((sR >> 5) << (3 + 2)) |
slouken@1895
  1992
                        ((sG >> 5) << (2)) | ((sB >> 6) << (0));
slouken@1895
  1993
                }
slouken@1895
  1994
                dst++;
slouken@1895
  1995
                src += srcbpp;
slouken@1895
  1996
            }
slouken@0
  1997
#endif
slouken@1895
  1998
            src += srcskip;
slouken@1895
  1999
            dst += dstskip;
slouken@1895
  2000
        }
slouken@1895
  2001
    } else {
slouken@1895
  2002
        while (height--) {
slouken@0
  2003
#ifdef USE_DUFFS_LOOP
slouken@1895
  2004
			/* *INDENT-OFF* */
slouken@0
  2005
			DUFFS_LOOP(
icculus@1162
  2006
				DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
slouken@0
  2007
								sR, sG, sB);
slouken@0
  2008
				if ( 1 ) {
slouken@0
  2009
				  	/* Pack RGB into 8bit pixel */
slouken@0
  2010
				  	*dst = map[((sR>>5)<<(3+2))|
slouken@0
  2011
						   ((sG>>5)<<(2))  |
slouken@0
  2012
						   ((sB>>6)<<(0))  ];
slouken@0
  2013
				}
slouken@0
  2014
				dst++;
slouken@0
  2015
				src += srcbpp;
slouken@0
  2016
			, width);
slouken@1895
  2017
			/* *INDENT-ON* */
slouken@0
  2018
#else
slouken@1895
  2019
            for (c = width; c; --c) {
slouken@1895
  2020
                DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
slouken@1895
  2021
                if (1) {
slouken@1895
  2022
                    /* Pack RGB into 8bit pixel */
slouken@1895
  2023
                    *dst = map[((sR >> 5) << (3 + 2)) |
slouken@1895
  2024
                               ((sG >> 5) << (2)) | ((sB >> 6) << (0))];
slouken@1895
  2025
                }
slouken@1895
  2026
                dst++;
slouken@1895
  2027
                src += srcbpp;
slouken@1895
  2028
            }
slouken@0
  2029
#endif /* USE_DUFFS_LOOP */
slouken@1895
  2030
            src += srcskip;
slouken@1895
  2031
            dst += dstskip;
slouken@1895
  2032
        }
slouken@1895
  2033
    }
slouken@0
  2034
}
icculus@1232
  2035
icculus@1232
  2036
/* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */
slouken@1895
  2037
static void
slouken@1895
  2038
Blit4to4MaskAlpha(SDL_BlitInfo * info)
icculus@1232
  2039
{
slouken@2262
  2040
    int width = info->dst_w;
slouken@2262
  2041
    int height = info->dst_h;
slouken@2262
  2042
    Uint32 *src = (Uint32 *) info->src;
slouken@2267
  2043
    int srcskip = info->src_skip;
slouken@2262
  2044
    Uint32 *dst = (Uint32 *) info->dst;
slouken@2267
  2045
    int dstskip = info->dst_skip;
slouken@2267
  2046
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@2267
  2047
    SDL_PixelFormat *dstfmt = info->dst_fmt;
icculus@1232
  2048
slouken@1895
  2049
    if (dstfmt->Amask) {
slouken@1895
  2050
        /* RGB->RGBA, SET_ALPHA */
slouken@2267
  2051
        Uint32 mask = (info->a >> dstfmt->Aloss) << dstfmt->Ashift;
icculus@1232
  2052
slouken@1895
  2053
        while (height--) {
slouken@1895
  2054
			/* *INDENT-OFF* */
icculus@1232
  2055
			DUFFS_LOOP(
icculus@1232
  2056
			{
icculus@1232
  2057
				*dst = *src | mask;
icculus@1232
  2058
				++dst;
icculus@1232
  2059
				++src;
icculus@1232
  2060
			},
icculus@1232
  2061
			width);
slouken@1895
  2062
			/* *INDENT-ON* */
slouken@1895
  2063
            src = (Uint32 *) ((Uint8 *) src + srcskip);
slouken@1895
  2064
            dst = (Uint32 *) ((Uint8 *) dst + dstskip);
slouken@1895
  2065
        }
slouken@1895
  2066
    } else {
slouken@1895
  2067
        /* RGBA->RGB, NO_ALPHA */
slouken@1895
  2068
        Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask;
icculus@1232
  2069
slouken@1895
  2070
        while (height--) {
slouken@1895
  2071
			/* *INDENT-OFF* */
icculus@1232
  2072
			DUFFS_LOOP(
icculus@1232
  2073
			{
icculus@1232
  2074
				*dst = *src & mask;
icculus@1232
  2075
				++dst;
icculus@1232
  2076
				++src;
icculus@1232
  2077
			},
icculus@1232
  2078
			width);
slouken@1895
  2079
			/* *INDENT-ON* */
slouken@1895
  2080
            src = (Uint32 *) ((Uint8 *) src + srcskip);
slouken@1895
  2081
            dst = (Uint32 *) ((Uint8 *) dst + dstskip);
slouken@1895
  2082
        }
slouken@1895
  2083
    }
icculus@1232
  2084
}
icculus@1232
  2085
slouken@1895
  2086
static void
slouken@1895
  2087
BlitNtoN(SDL_BlitInfo * info)
slouken@0
  2088
{
slouken@2262
  2089
    int width = info->dst_w;
slouken@2262
  2090
    int height = info->dst_h;
slouken@2262
  2091
    Uint8 *src = info->src;
slouken@2267
  2092
    int srcskip = info->src_skip;
slouken@2262
  2093
    Uint8 *dst = info->dst;
slouken@2267
  2094
    int dstskip = info->dst_skip;
slouken@2267
  2095
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@1895
  2096
    int srcbpp = srcfmt->BytesPerPixel;
slouken@2267
  2097
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@1895
  2098
    int dstbpp = dstfmt->BytesPerPixel;
slouken@2267
  2099
    unsigned alpha = dstfmt->Amask ? info->a : 0;
slouken@0
  2100
slouken@1895
  2101
    while (height--) {
slouken@1895
  2102
		/* *INDENT-OFF* */
slouken@0
  2103
		DUFFS_LOOP(
slouken@0
  2104
		{
slouken@1985
  2105
            Uint32 Pixel;
slouken@0
  2106
			unsigned sR;
slouken@0
  2107
			unsigned sG;
slouken@0
  2108
			unsigned sB;
icculus@1162
  2109
			DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB);
slouken@0
  2110
			ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
slouken@0
  2111
			dst += dstbpp;
slouken@0
  2112
			src += srcbpp;
slouken@0
  2113
		},
slouken@0
  2114
		width);
slouken@1895
  2115
		/* *INDENT-ON* */
slouken@1895
  2116
        src += srcskip;
slouken@1895
  2117
        dst += dstskip;
slouken@1895
  2118
    }
slouken@0
  2119
}
slouken@0
  2120
slouken@1895
  2121
static void
slouken@1895
  2122
BlitNtoNCopyAlpha(SDL_BlitInfo * info)
slouken@0
  2123
{
slouken@2262
  2124
    int width = info->dst_w;
slouken@2262
  2125
    int height = info->dst_h;
slouken@2262
  2126
    Uint8 *src = info->src;
slouken@2267
  2127
    int srcskip = info->src_skip;
slouken@2262
  2128
    Uint8 *dst = info->dst;
slouken@2267
  2129
    int dstskip = info->dst_skip;
slouken@2267
  2130
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@1895
  2131
    int srcbpp = srcfmt->BytesPerPixel;
slouken@2267
  2132
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@1895
  2133
    int dstbpp = dstfmt->BytesPerPixel;
slouken@1895
  2134
    int c;
slouken@0
  2135
slouken@1895
  2136
    while (height--) {
slouken@1895
  2137
        for (c = width; c; --c) {
slouken@1895
  2138
            Uint32 Pixel;
slouken@1895
  2139
            unsigned sR, sG, sB, sA;
slouken@1895
  2140
            DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
slouken@1895
  2141
            ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
slouken@1895
  2142
            dst += dstbpp;
slouken@1895
  2143
            src += srcbpp;
slouken@1895
  2144
        }
slouken@1895
  2145
        src += srcskip;
slouken@1895
  2146
        dst += dstskip;
slouken@1895
  2147
    }
slouken@0
  2148
}
slouken@0
  2149
slouken@1895
  2150
static void
slouken@1895
  2151
BlitNto1Key(SDL_BlitInfo * info)
slouken@0
  2152
{
slouken@2262
  2153
    int width = info->dst_w;
slouken@2262
  2154
    int height = info->dst_h;
slouken@2262
  2155
    Uint8 *src = info->src;
slouken@2267
  2156
    int srcskip = info->src_skip;
slouken@2262
  2157
    Uint8 *dst = info->dst;
slouken@2267
  2158
    int dstskip = info->dst_skip;
slouken@2267
  2159
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@1895
  2160
    const Uint8 *palmap = info->table;
slouken@2267
  2161
    Uint32 ckey = info->colorkey;
slouken@1895
  2162
    Uint32 rgbmask = ~srcfmt->Amask;
slouken@1895
  2163
    int srcbpp;
slouken@1895
  2164
    Uint32 Pixel;
slouken@1895
  2165
    unsigned sR, sG, sB;
slouken@0
  2166
slouken@1895
  2167
    /* Set up some basic variables */
slouken@1895
  2168
    srcbpp = srcfmt->BytesPerPixel;
slouken@1895
  2169
    ckey &= rgbmask;
slouken@0
  2170
slouken@1895
  2171
    if (palmap == NULL) {
slouken@1895
  2172
        while (height--) {
slouken@1895
  2173
			/* *INDENT-OFF* */
slouken@0
  2174
			DUFFS_LOOP(
slouken@0
  2175
			{
icculus@1162
  2176
				DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
slouken@0
  2177
								sR, sG, sB);
icculus@1162
  2178
				if ( (Pixel & rgbmask) != ckey ) {
slouken@0
  2179
				  	/* Pack RGB into 8bit pixel */
slouken@1428
  2180
				  	*dst = (Uint8)(((sR>>5)<<(3+2))|
slouken@1428
  2181
						           ((sG>>5)<<(2)) |
slouken@1428
  2182
						           ((sB>>6)<<(0)));
slouken@0
  2183
				}
slouken@0
  2184
				dst++;
slouken@0
  2185
				src += srcbpp;
slouken@0
  2186
			},
slouken@0
  2187
			width);
slouken@1895
  2188
			/* *INDENT-ON* */
slouken@1895
  2189
            src += srcskip;
slouken@1895
  2190
            dst += dstskip;
slouken@1895
  2191
        }
slouken@1895
  2192
    } else {
slouken@1895
  2193
        while (height--) {
slouken@1895
  2194
			/* *INDENT-OFF* */
slouken@0
  2195
			DUFFS_LOOP(
slouken@0
  2196
			{
icculus@1162
  2197
				DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel,
slouken@0
  2198
								sR, sG, sB);
icculus@1162
  2199
				if ( (Pixel & rgbmask) != ckey ) {
slouken@0
  2200
				  	/* Pack RGB into 8bit pixel */
slouken@1428
  2201
				  	*dst = (Uint8)palmap[((sR>>5)<<(3+2))|
slouken@1428
  2202
							             ((sG>>5)<<(2))  |
slouken@1428
  2203
							             ((sB>>6)<<(0))  ];
slouken@0
  2204
				}
slouken@0
  2205
				dst++;
slouken@0
  2206
				src += srcbpp;
slouken@0
  2207
			},
slouken@0
  2208
			width);
slouken@1895
  2209
			/* *INDENT-ON* */
slouken@1895
  2210
            src += srcskip;
slouken@1895
  2211
            dst += dstskip;
slouken@1895
  2212
        }
slouken@1895
  2213
    }
slouken@0
  2214
}
slouken@0
  2215
slouken@1895
  2216
static void
slouken@1895
  2217
Blit2to2Key(SDL_BlitInfo * info)
slouken@0
  2218
{
slouken@2262
  2219
    int width = info->dst_w;
slouken@2262
  2220
    int height = info->dst_h;
slouken@2262
  2221
    Uint16 *srcp = (Uint16 *) info->src;
slouken@2267
  2222
    int srcskip = info->src_skip;
slouken@2262
  2223
    Uint16 *dstp = (Uint16 *) info->dst;
slouken@2267
  2224
    int dstskip = info->dst_skip;
slouken@2267
  2225
    Uint32 ckey = info->colorkey;
slouken@2267
  2226
    Uint32 rgbmask = ~info->src_fmt->Amask;
slouken@0
  2227
slouken@1895
  2228
    /* Set up some basic variables */
slouken@1895
  2229
    srcskip /= 2;
slouken@1895
  2230
    dstskip /= 2;
slouken@1895
  2231
    ckey &= rgbmask;
slouken@0
  2232
slouken@1895
  2233
    while (height--) {
slouken@1895
  2234
		/* *INDENT-OFF* */
slouken@0
  2235
		DUFFS_LOOP(
slouken@0
  2236
		{
slouken@0
  2237
			if ( (*srcp & rgbmask) != ckey ) {
slouken@0
  2238
				*dstp = *srcp;
slouken@0
  2239
			}
slouken@0
  2240
			dstp++;
slouken@0
  2241
			srcp++;
slouken@0
  2242
		},
slouken@0
  2243
		width);
slouken@1895
  2244
		/* *INDENT-ON* */
slouken@1895
  2245
        srcp += srcskip;
slouken@1895
  2246
        dstp += dstskip;
slouken@1895
  2247
    }
slouken@0
  2248
}
slouken@0
  2249
slouken@1895
  2250
static void
slouken@1895
  2251
BlitNtoNKey(SDL_BlitInfo * info)
slouken@0
  2252
{
slouken@2262
  2253
    int width = info->dst_w;
slouken@2262
  2254
    int height = info->dst_h;
slouken@2262
  2255
    Uint8 *src = info->src;
slouken@2267
  2256
    int srcskip = info->src_skip;
slouken@2262
  2257
    Uint8 *dst = info->dst;
slouken@2267
  2258
    int dstskip = info->dst_skip;
slouken@2267
  2259
    Uint32 ckey = info->colorkey;
slouken@2267
  2260
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@2267
  2261
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@1895
  2262
    int srcbpp = srcfmt->BytesPerPixel;
slouken@1895
  2263
    int dstbpp = dstfmt->BytesPerPixel;
slouken@2267
  2264
    unsigned alpha = dstfmt->Amask ? info->a : 0;
slouken@1895
  2265
    Uint32 rgbmask = ~srcfmt->Amask;
slouken@1543
  2266
slouken@1895
  2267
    /* Set up some basic variables */
slouken@1895
  2268
    ckey &= rgbmask;
slouken@0
  2269
slouken@1895
  2270
    while (height--) {
slouken@1895
  2271
		/* *INDENT-OFF* */
slouken@0
  2272
		DUFFS_LOOP(
slouken@0
  2273
		{
slouken@1985
  2274
            Uint32 Pixel;
slouken@0
  2275
			unsigned sR;
slouken@0
  2276
			unsigned sG;
slouken@0
  2277
			unsigned sB;
icculus@1162
  2278
			RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel);
slouken@1543
  2279
			if ( (Pixel & rgbmask) != ckey ) {
slouken@1985
  2280
                RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB);
slouken@1985
  2281
				ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
slouken@0
  2282
			}
slouken@0
  2283
			dst += dstbpp;
slouken@0
  2284
			src += srcbpp;
slouken@0
  2285
		},
slouken@0
  2286
		width);
slouken@1895
  2287
		/* *INDENT-ON* */
slouken@1895
  2288
        src += srcskip;
slouken@1895
  2289
        dst += dstskip;
slouken@1895
  2290
    }
slouken@0
  2291
}
slouken@0
  2292
slouken@1895
  2293
static void
slouken@1895
  2294
BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info)
slouken@0
  2295
{
slouken@2262
  2296
    int width = info->dst_w;
slouken@2262
  2297
    int height = info->dst_h;
slouken@2262
  2298
    Uint8 *src = info->src;
slouken@2267
  2299
    int srcskip = info->src_skip;
slouken@2262
  2300
    Uint8 *dst = info->dst;
slouken@2267
  2301
    int dstskip = info->dst_skip;
slouken@2267
  2302
    Uint32 ckey = info->colorkey;
slouken@2267
  2303
    SDL_PixelFormat *srcfmt = info->src_fmt;
slouken@2267
  2304
    SDL_PixelFormat *dstfmt = info->dst_fmt;
slouken@1895
  2305
    Uint32 rgbmask = ~srcfmt->Amask;
slouken@0
  2306
slouken@1895
  2307
    Uint8 srcbpp;
slouken@1895
  2308
    Uint8 dstbpp;
slouken@1895
  2309
    Uint32 Pixel;
slouken@1895
  2310
    unsigned sR, sG, sB, sA;
slouken@0
  2311
slouken@1895
  2312
    /* Set up some basic variables */
slouken@1895
  2313
    srcbpp = srcfmt->BytesPerPixel;
slouken@1895
  2314
    dstbpp = dstfmt->BytesPerPixel;
slouken@1895
  2315
    ckey &= rgbmask;
slouken@0
  2316
slouken@1895
  2317
    while (height--) {
slouken@1895
  2318
		/* *INDENT-OFF* */
slouken@0
  2319
		DUFFS_LOOP(
slouken@0
  2320
		{
slouken@1985
  2321
			DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
icculus@1162
  2322
			if ( (Pixel & rgbmask) != ckey ) {
slouken@1985
  2323
				  ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, sA);
slouken@0
  2324
			}
slouken@0
  2325
			dst += dstbpp;
slouken@0
  2326
			src += srcbpp;
slouken@0
  2327
		},
slouken@0
  2328
		width);
slouken@1895
  2329
		/* *INDENT-ON* */
slouken@1895
  2330
        src += srcskip;
slouken@1895
  2331
        dst += dstskip;
slouken@1895
  2332
    }
slouken@0
  2333
}
slouken@0
  2334
slouken@0
  2335
/* Normal N to N optimized blitters */
slouken@1895
  2336
struct blit_table
slouken@1895
  2337
{
slouken@1895
  2338
    Uint32 srcR, srcG, srcB;
slouken@1895
  2339
    int dstbpp;
slouken@1895
  2340
    Uint32 dstR, dstG, dstB;
slouken@1895
  2341
    Uint32 blit_features;
slouken@2267
  2342
    SDL_BlitFunc blitfunc;
slouken@1895
  2343
    enum
slouken@1895
  2344
    { NO_ALPHA = 1, SET_ALPHA = 2, COPY_ALPHA = 4 } alpha;
slouken@0
  2345
};
slouken@91
  2346
static const struct blit_table normal_blit_1[] = {
slouken@1895
  2347
    /* Default for 8-bit RGB source, an invalid combination */
slouken@2257
  2348
    {0, 0, 0, 0, 0, 0, 0, 0, NULL},
slouken@0
  2349
};
slouken@2735
  2350
slouken@91
  2351
static const struct blit_table normal_blit_2[] = {
slouken@5389
  2352
#if SDL_ALTIVEC_BLITTERS
slouken@5389
  2353
    /* has-altivec */
slouken@5389
  2354
    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000,
slouken@5389
  2355
     0x00000000,
slouken@5389
  2356
     2, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
slouken@5389
  2357
    {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000,
slouken@5389
  2358
     0x00000000,
slouken@5389
  2359
     2, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
slouken@5389
  2360
#endif
slouken@1895
  2361
    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00,
slouken@1895
  2362
     0x000000FF,
slouken@2257
  2363
     0, Blit_RGB565_ARGB8888, SET_ALPHA},
slouken@1895
  2364
    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00,
slouken@1895
  2365
     0x00FF0000,
slouken@2257
  2366
     0, Blit_RGB565_ABGR8888, SET_ALPHA},
slouken@1895
  2367
    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000,
slouken@1895
  2368
     0x0000FF00,
slouken@2257
  2369
     0, Blit_RGB565_RGBA8888, SET_ALPHA},
slouken@1895
  2370
    {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000,
slouken@1895
  2371
     0xFF000000,
slouken@2257
  2372
     0, Blit_RGB565_BGRA8888, SET_ALPHA},
slouken@0
  2373
slouken@0
  2374
    /* Default for 16-bit RGB source, used if no other blitter matches */
slouken@2257
  2375
    {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
slouken@0
  2376
};
slouken@2735
  2377
slouken@91
  2378
static const struct blit_table normal_blit_3[] = {
slouken@1895
  2379
    /* Default for 24-bit RGB source, never optimized */
slouken@2257
  2380
    {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
slouken@0
  2381
};
slouken@2735
  2382
slouken@91
  2383
static const struct blit_table normal_blit_4[] = {
slouken@5389
  2384
#if SDL_ALTIVEC_BLITTERS
slouken@5389
  2385
    /* has-altivec | dont-use-prefetch */
slouken@5389
  2386
    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000,
slouken@5389
  2387
     0x00000000,
slouken@5389
  2388
     6, ConvertAltivec32to32_noprefetch,
slouken@5389
  2389
     NO_ALPHA | COPY_ALPHA | SET_ALPHA},
slouken@5389
  2390
    /* has-altivec */
slouken@5389
  2391
    {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000,
slouken@5389
  2392
     0x00000000,
slouken@5389
  2393
     2, ConvertAltivec32to32_prefetch,
slouken@5389
  2394
     NO_ALPHA | COPY_ALPHA | SET_ALPHA},
slouken@5389
  2395
    /* has-altivec */
slouken@5389
  2396
    {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0,
slouken@5389
  2397
     0x0000001F,
slouken@5389
  2398
     2, Blit_RGB888_RGB565Altivec, NO_ALPHA},
slouken@5389
  2399
#endif
slouken@1895
  2400
    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0,
slouken@1895
  2401
     0x0000001F,
slouken@2257
  2402
     0, Blit_RGB888_RGB565, NO_ALPHA},
slouken@1895
  2403
    {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0,
slouken@1895
  2404
     0x0000001F,
slouken@2257
  2405
     0, Blit_RGB888_RGB555, NO_ALPHA},
slouken@1895
  2406
    /* Default for 32-bit RGB source, used if no other blitter matches */
slouken@2257
  2407
    {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
slouken@0
  2408
};
slouken@2735
  2409
slouken@3162
  2410
static const struct blit_table *const normal_blit[] = {
slouken@1895
  2411
    normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
slouken@0
  2412
};
slouken@0
  2413
icculus@1047
  2414
/* Mask matches table, or table entry is zero */
icculus@1047
  2415
#define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000))
icculus@1047
  2416
slouken@2267
  2417
SDL_BlitFunc
slouken@2267
  2418
SDL_CalculateBlitN(SDL_Surface * surface)
slouken@0
  2419
{
slouken@1895
  2420
    SDL_PixelFormat *srcfmt;
slouken@1895
  2421
    SDL_PixelFormat *dstfmt;
slouken@1895
  2422
    const struct blit_table *table;
slouken@1895
  2423
    int which;
slouken@2267
  2424
    SDL_BlitFunc blitfun;
slouken@0
  2425
slouken@1895
  2426
    /* Set up data for choosing the blit */
slouken@1895
  2427
    srcfmt = surface->format;
slouken@1895
  2428
    dstfmt = surface->map->dst->format;
slouken@0
  2429
slouken@1895
  2430
    /* We don't support destinations less than 8-bits */
slouken@1895
  2431
    if (dstfmt->BitsPerPixel < 8) {
slouken@1895
  2432
        return (NULL);
slouken@1895
  2433
    }
slouken@0
  2434
slouken@2853
  2435
    switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
slouken@2267
  2436
    case 0:
slouken@2267
  2437
        blitfun = NULL;
slouken@2267
  2438
        if (dstfmt->BitsPerPixel == 8) {
slouken@2267
  2439
            /* We assume 8-bit destinations are palettized */
slouken@2267
  2440
            if ((srcfmt->BytesPerPixel == 4) &&
slouken@2267
  2441
                (srcfmt->Rmask == 0x00FF0000) &&
slouken@2267
  2442
                (srcfmt->Gmask == 0x0000FF00) &&
slouken@2267
  2443
                (srcfmt->Bmask == 0x000000FF)) {
slouken@2267
  2444
                if (surface->map->info.table) {
slouken@2267
  2445
                    blitfun = Blit_RGB888_index8_map;
slouken@2267
  2446
                } else {
slouken@2267
  2447
                    blitfun = Blit_RGB888_index8;
slouken@2267
  2448
                }
slouken@2267
  2449
            } else {
slouken@2267
  2450
                blitfun = BlitNto1;
slouken@2267
  2451
            }
slouken@2267
  2452
        } else {
slouken@2267
  2453
            /* Now the meat, choose the blitter we want */
slouken@2267
  2454
            int a_need = NO_ALPHA;
slouken@2267
  2455
            if (dstfmt->Amask)
slouken@2267
  2456
                a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
slouken@2267
  2457
            table = normal_blit[srcfmt->BytesPerPixel - 1];
slouken@2267
  2458
            for (which = 0; table[which].dstbpp; ++which) {
slouken@2267
  2459
                if (MASKOK(srcfmt->Rmask, table[which].srcR) &&
slouken@2267
  2460
                    MASKOK(srcfmt->Gmask, table[which].srcG) &&
slouken@2267
  2461
                    MASKOK(srcfmt->Bmask, table[which].srcB) &&
slouken@2267
  2462
                    MASKOK(dstfmt->Rmask, table[which].dstR) &&
slouken@2267
  2463
                    MASKOK(dstfmt->Gmask, table[which].dstG) &&
slouken@2267
  2464
                    MASKOK(dstfmt->Bmask, table[which].dstB) &&
slouken@2267
  2465
                    dstfmt->BytesPerPixel == table[which].dstbpp &&
slouken@2267
  2466
                    (a_need & table[which].alpha) == a_need &&
slouken@2267
  2467
                    ((table[which].blit_features & GetBlitFeatures()) ==
slouken@2267
  2468
                     table[which].blit_features))
slouken@2267
  2469
                    break;
slouken@2267
  2470
            }
slouken@2267
  2471
            blitfun = table[which].blitfunc;
slouken@2267
  2472
slouken@2267
  2473
            if (blitfun == BlitNtoN) {  /* default C fallback catch-all. Slow! */
slouken@2267
  2474
                /* Fastpath C fallback: 32bit RGB<->RGBA blit with matching RGB */
slouken@2267
  2475
                if (srcfmt->BytesPerPixel == 4 && dstfmt->BytesPerPixel == 4
slouken@2267
  2476
                    && srcfmt->Rmask == dstfmt->Rmask
slouken@2267
  2477
                    && srcfmt->Gmask == dstfmt->Gmask
slouken@2267
  2478
                    && srcfmt->Bmask == dstfmt->Bmask) {
slouken@2267
  2479
                    blitfun = Blit4to4MaskAlpha;
slouken@2267
  2480
                } else if (a_need == COPY_ALPHA) {
slouken@2267
  2481
                    blitfun = BlitNtoNCopyAlpha;
slouken@2267
  2482
                }
slouken@2267
  2483
            }
slouken@2267
  2484
        }
slouken@2267
  2485
        return (blitfun);
slouken@2267
  2486
slouken@2267
  2487
    case SDL_COPY_COLORKEY:
slouken@1895
  2488
        /* colorkey blit: Here we don't have too many options, mostly
slouken@1895
  2489
           because RLE is the preferred fast way to deal with this.
slouken@1895
  2490
           If a particular case turns out to be useful we'll add it. */
slouken@1895
  2491
slouken@1895
  2492
        if (srcfmt->BytesPerPixel == 2 && surface->map->identity)
slouken@1895
  2493
            return Blit2to2Key;
slouken@1895
  2494
        else if (dstfmt->BytesPerPixel == 1)
slouken@1895
  2495
            return BlitNto1Key;
slouken@1895
  2496
        else {
slouken@5389
  2497
#if SDL_ALTIVEC_BLITTERS
slouken@5389
  2498
            if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4)
slouken@5389
  2499
                && SDL_HasAltiVec()) {
slouken@5389
  2500
                return Blit32to32KeyAltivec;
slouken@5389
  2501
            } else
slouken@5389
  2502
#endif
slouken@2267
  2503
            if (srcfmt->Amask && dstfmt->Amask) {
slouken@1895
  2504
                return BlitNtoNKeyCopyAlpha;
slouken@2267
  2505
            } else {
slouken@1895
  2506
                return BlitNtoNKey;
slouken@1895
  2507
            }
slouken@1895
  2508
        }
slouken@1895
  2509
    }
slouken@0
  2510
slouken@2267
  2511
    return NULL;
slouken@0
  2512
}
slouken@1895
  2513
slouken@1895
  2514
/* vi: set ts=4 sw=4 expandtab: */