PageRenderTime 38ms CodeModel.GetById 13ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sdl-1.3/src/video/SDL_blit.c

https://github.com/aichunyu/FFPlayer
C | 280 lines | 205 code | 30 blank | 45 comment | 64 complexity | 3479c5cfb8e7440383c39fb432ddeaa7 MD5 | raw file
  1/*
  2  Simple DirectMedia Layer
  3  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
  4
  5  This software is provided 'as-is', without any express or implied
  6  warranty.  In no event will the authors be held liable for any damages
  7  arising from the use of this software.
  8
  9  Permission is granted to anyone to use this software for any purpose,
 10  including commercial applications, and to alter it and redistribute it
 11  freely, subject to the following restrictions:
 12
 13  1. The origin of this software must not be misrepresented; you must not
 14     claim that you wrote the original software. If you use this software
 15     in a product, an acknowledgment in the product documentation would be
 16     appreciated but is not required.
 17  2. Altered source versions must be plainly marked as such, and must not be
 18     misrepresented as being the original software.
 19  3. This notice may not be removed or altered from any source distribution.
 20*/
 21#include "SDL_config.h"
 22
 23#include "SDL_video.h"
 24#include "SDL_sysvideo.h"
 25#include "SDL_blit.h"
 26#include "SDL_blit_auto.h"
 27#include "SDL_blit_copy.h"
 28#include "SDL_blit_slow.h"
 29#include "SDL_RLEaccel_c.h"
 30#include "SDL_pixels_c.h"
 31
 32/* The general purpose software blit routine */
 33static int
 34SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
 35             SDL_Surface * dst, SDL_Rect * dstrect)
 36{
 37    int okay;
 38    int src_locked;
 39    int dst_locked;
 40
 41    /* Everything is okay at the beginning...  */
 42    okay = 1;
 43
 44    /* Lock the destination if it's in hardware */
 45    dst_locked = 0;
 46    if (SDL_MUSTLOCK(dst)) {
 47        if (SDL_LockSurface(dst) < 0) {
 48            okay = 0;
 49        } else {
 50            dst_locked = 1;
 51        }
 52    }
 53    /* Lock the source if it's in hardware */
 54    src_locked = 0;
 55    if (SDL_MUSTLOCK(src)) {
 56        if (SDL_LockSurface(src) < 0) {
 57            okay = 0;
 58        } else {
 59            src_locked = 1;
 60        }
 61    }
 62
 63    /* Set up source and destination buffer pointers, and BLIT! */
 64    if (okay && srcrect->w && srcrect->h) {
 65        SDL_BlitFunc RunBlit;
 66        SDL_BlitInfo *info = &src->map->info;
 67
 68        /* Set up the blit information */
 69        info->src = (Uint8 *) src->pixels +
 70            (Uint16) srcrect->y * src->pitch +
 71            (Uint16) srcrect->x * info->src_fmt->BytesPerPixel;
 72        info->src_w = srcrect->w;
 73        info->src_h = srcrect->h;
 74        info->src_pitch = src->pitch;
 75        info->src_skip =
 76            info->src_pitch - info->src_w * info->src_fmt->BytesPerPixel;
 77        info->dst =
 78            (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch +
 79            (Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
 80        info->dst_w = dstrect->w;
 81        info->dst_h = dstrect->h;
 82        info->dst_pitch = dst->pitch;
 83        info->dst_skip =
 84            info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel;
 85        RunBlit = (SDL_BlitFunc) src->map->data;
 86
 87        /* Run the actual software blit */
 88        RunBlit(info);
 89    }
 90
 91    /* We need to unlock the surfaces if they're locked */
 92    if (dst_locked) {
 93        SDL_UnlockSurface(dst);
 94    }
 95    if (src_locked) {
 96        SDL_UnlockSurface(src);
 97    }
 98    /* Blit is done! */
 99    return (okay ? 0 : -1);
100}
101
102#ifdef __MACOSX__
103#include <sys/sysctl.h>
104
105static SDL_bool
106SDL_UseAltivecPrefetch()
107{
108    const char key[] = "hw.l3cachesize";
109    u_int64_t result = 0;
110    size_t typeSize = sizeof(result);
111
112    if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) {
113        return SDL_TRUE;
114    } else {
115        return SDL_FALSE;
116    }
117}
118#else
119static SDL_bool
120SDL_UseAltivecPrefetch()
121{
122    /* Just guess G4 */
123    return SDL_TRUE;
124}
125#endif /* __MACOSX__ */
126
127static SDL_BlitFunc
128SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
129                   SDL_BlitFuncEntry * entries)
130{
131    int i, flagcheck;
132    static Uint32 features = 0xffffffff;
133
134    /* Get the available CPU features */
135    if (features == 0xffffffff) {
136        const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");
137
138        features = SDL_CPU_ANY;
139
140        /* Allow an override for testing .. */
141        if (override) {
142            SDL_sscanf(override, "%u", &features);
143        } else {
144            if (SDL_HasMMX()) {
145                features |= SDL_CPU_MMX;
146            }
147            if (SDL_Has3DNow()) {
148                features |= SDL_CPU_3DNOW;
149            }
150            if (SDL_HasSSE()) {
151                features |= SDL_CPU_SSE;
152            }
153            if (SDL_HasSSE2()) {
154                features |= SDL_CPU_SSE2;
155            }
156            if (SDL_HasAltiVec()) {
157                if (SDL_UseAltivecPrefetch()) {
158                    features |= SDL_CPU_ALTIVEC_PREFETCH;
159                } else {
160                    features |= SDL_CPU_ALTIVEC_NOPREFETCH;
161                }
162            }
163        }
164    }
165
166    for (i = 0; entries[i].func; ++i) {
167        /* Check for matching pixel formats */
168        if (src_format != entries[i].src_format) {
169            continue;
170        }
171        if (dst_format != entries[i].dst_format) {
172            continue;
173        }
174
175        /* Check modulation flags */
176        flagcheck =
177            (flags & (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA));
178        if ((flagcheck & entries[i].flags) != flagcheck) {
179            continue;
180        }
181
182        /* Check blend flags */
183        flagcheck =
184            (flags &
185             (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD));
186        if ((flagcheck & entries[i].flags) != flagcheck) {
187            continue;
188        }
189
190        /* Check colorkey flag */
191        flagcheck = (flags & SDL_COPY_COLORKEY);
192        if ((flagcheck & entries[i].flags) != flagcheck) {
193            continue;
194        }
195
196        /* Check scaling flags */
197        flagcheck = (flags & SDL_COPY_NEAREST);
198        if ((flagcheck & entries[i].flags) != flagcheck) {
199            continue;
200        }
201
202        /* Check CPU features */
203        flagcheck = entries[i].cpu;
204        if ((flagcheck & features) != flagcheck) {
205            continue;
206        }
207
208        /* We found the best one! */
209        return entries[i].func;
210    }
211    return NULL;
212}
213
214/* Figure out which of many blit routines to set up on a surface */
215int
216SDL_CalculateBlit(SDL_Surface * surface)
217{
218    SDL_BlitFunc blit = NULL;
219    SDL_BlitMap *map = surface->map;
220    SDL_Surface *dst = map->dst;
221
222    /* Clean everything out to start */
223    if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
224        SDL_UnRLESurface(surface, 1);
225    }
226    map->blit = SDL_SoftBlit;
227    map->info.src_fmt = surface->format;
228    map->info.src_pitch = surface->pitch;
229    map->info.dst_fmt = dst->format;
230    map->info.dst_pitch = dst->pitch;
231
232    /* See if we can do RLE acceleration */
233    if (map->info.flags & SDL_COPY_RLE_DESIRED) {
234        if (SDL_RLESurface(surface) == 0) {
235            return 0;
236        }
237    }
238
239    /* Choose a standard blit function */
240    if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) {
241        blit = SDL_BlitCopy;
242    } else if (surface->format->BitsPerPixel < 8) {
243        blit = SDL_CalculateBlit0(surface);
244    } else if (surface->format->BytesPerPixel == 1) {
245        blit = SDL_CalculateBlit1(surface);
246    } else if (map->info.flags & SDL_COPY_BLEND) {
247        blit = SDL_CalculateBlitA(surface);
248    } else {
249        blit = SDL_CalculateBlitN(surface);
250    }
251    if (blit == NULL) {
252        Uint32 src_format = surface->format->format;
253        Uint32 dst_format = dst->format->format;
254
255        blit =
256            SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
257                               SDL_GeneratedBlitFuncTable);
258    }
259#ifndef TEST_SLOW_BLIT
260    if (blit == NULL)
261#endif
262    {
263        if (surface->format->BytesPerPixel > 1
264            && dst->format->BytesPerPixel > 1) {
265            blit = SDL_Blit_Slow;
266        }
267    }
268    map->data = blit;
269
270    /* Make sure we have a blit function */
271    if (blit == NULL) {
272        SDL_InvalidateMap(map);
273        SDL_SetError("Blit combination not supported");
274        return (-1);
275    }
276
277    return (0);
278}
279
280/* vi: set ts=4 sw=4 expandtab: */