src/video/SDL_blit_copy.c
author Sam Lantinga
Thu, 16 Aug 2007 06:20:51 +0000
changeset 2250 e1d228456537
parent 2249 5a58b57b6724
child 2252 b80e3d57941f
permissions -rw-r--r--
Fixed a few compiler warnings.
Added SDL_blit_copy.c to the Visual C++ project

The SSE and MMX intrinsics don't compile on Visual Studio yet...
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_cpuinfo.h"
    25 #include "SDL_video.h"
    26 #include "SDL_blit.h"
    27 #include "SDL_blit_copy.h"
    28 
    29 
    30 #ifdef __MMX__
    31 static __inline__ void
    32 SDL_memcpyMMX(Uint8 * dst, const Uint8 * src, int len)
    33 {
    34     int i;
    35 
    36     __m64 values[8];
    37     for (i = len / 64; i--;) {
    38         _mm_prefetch(src, _MM_HINT_NTA);
    39         values[0] = *(__m64 *) (src + 0);
    40         values[1] = *(__m64 *) (src + 8);
    41         values[2] = *(__m64 *) (src + 16);
    42         values[3] = *(__m64 *) (src + 24);
    43         values[4] = *(__m64 *) (src + 32);
    44         values[5] = *(__m64 *) (src + 40);
    45         values[6] = *(__m64 *) (src + 48);
    46         values[7] = *(__m64 *) (src + 56);
    47         _mm_stream_pi((__m64 *) (dst + 0), values[0]);
    48         _mm_stream_pi((__m64 *) (dst + 8), values[1]);
    49         _mm_stream_pi((__m64 *) (dst + 16), values[2]);
    50         _mm_stream_pi((__m64 *) (dst + 24), values[3]);
    51         _mm_stream_pi((__m64 *) (dst + 32), values[4]);
    52         _mm_stream_pi((__m64 *) (dst + 40), values[5]);
    53         _mm_stream_pi((__m64 *) (dst + 48), values[6]);
    54         _mm_stream_pi((__m64 *) (dst + 56), values[7]);
    55         src += 64;
    56         dst += 64;
    57     }
    58 
    59     if (len & 63)
    60         SDL_memcpy(dst, src, len & 63);
    61 }
    62 #endif /* __MMX__ */
    63 
    64 #ifdef __SSE__
    65 static __inline__ void
    66 SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len)
    67 {
    68     int i;
    69 
    70     __m128 values[4];
    71     for (i = len / 64; i--;) {
    72         _mm_prefetch(src, _MM_HINT_NTA);
    73         values[0] = *(__m128 *) (src + 0);
    74         values[1] = *(__m128 *) (src + 16);
    75         values[2] = *(__m128 *) (src + 32);
    76         values[3] = *(__m128 *) (src + 48);
    77         _mm_stream_ps((float *) (dst + 0), values[0]);
    78         _mm_stream_ps((float *) (dst + 16), values[1]);
    79         _mm_stream_ps((float *) (dst + 32), values[2]);
    80         _mm_stream_ps((float *) (dst + 48), values[3]);
    81         src += 64;
    82         dst += 64;
    83     }
    84 
    85     if (len & 63)
    86         SDL_memcpy(dst, src, len & 63);
    87 }
    88 #endif /* __SSE__ */
    89 
    90 void
    91 SDL_BlitCopy(SDL_BlitInfo * info)
    92 {
    93     Uint8 *src, *dst;
    94     int w, h;
    95     int srcskip, dstskip;
    96 
    97     w = info->d_width * info->dst->BytesPerPixel;
    98     h = info->d_height;
    99     src = info->s_pixels;
   100     dst = info->d_pixels;
   101     srcskip = w + info->s_skip;
   102     dstskip = w + info->d_skip;
   103 
   104 #ifdef __SSE__
   105     if (SDL_HasSSE() && !((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) {
   106         while (h--) {
   107             SDL_memcpySSE(dst, src, w);
   108             src += srcskip;
   109             dst += dstskip;
   110         }
   111         return;
   112     }
   113 #endif
   114 
   115 #ifdef __MMX__
   116     if (SDL_HasMMX() && !((uintptr_t) src & 7) && !((uintptr_t) dst & 7)) {
   117         while (h--) {
   118             SDL_memcpyMMX(dst, src, w);
   119             src += srcskip;
   120             dst += dstskip;
   121         }
   122         _mm_empty();
   123         return;
   124     }
   125 #endif
   126 
   127     while (h--) {
   128         SDL_memcpy(dst, src, w);
   129         src += srcskip;
   130         dst += dstskip;
   131     }
   132 }
   133 
   134 void
   135 SDL_BlitCopyOverlap(SDL_BlitInfo * info)
   136 {
   137     Uint8 *src, *dst;
   138     int w, h;
   139     int skip;
   140 
   141     w = info->d_width * info->dst->BytesPerPixel;
   142     h = info->d_height;
   143     src = info->s_pixels;
   144     dst = info->d_pixels;
   145     skip = w + info->s_skip;
   146     if ((dst < src) || (dst >= (src + h * skip))) {
   147         SDL_BlitCopy(info);
   148     } else {
   149         src += ((h - 1) * skip);
   150         dst += ((h - 1) * skip);
   151         while (h--) {
   152             SDL_revcpy(dst, src, w);
   153             src -= skip;
   154             dst -= skip;
   155         }
   156     }
   157 }
   158 
   159 /* vi: set ts=4 sw=4 expandtab: */