zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_blit.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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 */
33 static int
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 && !SDL_RectEmpty(srcrect)) {
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 
105 static SDL_bool
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
119 static SDL_bool
121 {
122  /* Just guess G4 */
123  return SDL_TRUE;
124 }
125 #endif /* __MACOSX__ */
126 
127 static SDL_BlitFunc
128 SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
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 =
178  if ((flagcheck & entries[i].flags) != flagcheck) {
179  continue;
180  }
181 
182  /* Check blend flags */
183  flagcheck =
184  (flags &
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 */
215 int
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 &&
244  blit = SDL_CalculateBlit0(surface);
245  } else if (surface->format->BytesPerPixel == 1 &&
247  blit = SDL_CalculateBlit1(surface);
248  } else if (map->info.flags & SDL_COPY_BLEND) {
249  blit = SDL_CalculateBlitA(surface);
250  } else {
251  blit = SDL_CalculateBlitN(surface);
252  }
253  if (blit == NULL) {
254  Uint32 src_format = surface->format->format;
255  Uint32 dst_format = dst->format->format;
256 
257  blit =
258  SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
260  }
261 #ifndef TEST_SLOW_BLIT
262  if (blit == NULL)
263 #endif
264  {
265  Uint32 src_format = surface->format->format;
266  Uint32 dst_format = dst->format->format;
267 
268  if (!SDL_ISPIXELFORMAT_INDEXED(src_format) &&
269  !SDL_ISPIXELFORMAT_FOURCC(src_format) &&
270  !SDL_ISPIXELFORMAT_INDEXED(dst_format) &&
271  !SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
272  blit = SDL_Blit_Slow;
273  }
274  }
275  map->data = blit;
276 
277  /* Make sure we have a blit function */
278  if (blit == NULL) {
279  SDL_InvalidateMap(map);
280  return SDL_SetError("Blit combination not supported");
281  }
282 
283  return 0;
284 }
285 
286 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlitFunc func
Definition: SDL_blit.h:81
#define SDL_CPU_MMX
Definition: SDL_blit.h:48
#define SDL_COPY_MODULATE_COLOR
Definition: SDL_blit.h:34
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface)
Definition: SDL_blit_N.c:2500
SDL_blit blit
Definition: SDL_blit.h:89
int src_skip
Definition: SDL_blit.h:60
#define NULL
Definition: ftobjs.h:61
DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void)
Definition: SDL_cpuinfo.c:575
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
Uint8 BytesPerPixel
Definition: SDL_pixels.h:277
SDL_bool
Definition: SDL_stdinc.h:116
#define SDL_COPY_MOD
Definition: SDL_blit.h:38
SDL_PixelFormat * src_fmt
Definition: SDL_blit.h:65
void SDL_Blit_Slow(SDL_BlitInfo *info)
Definition: SDL_blit_slow.c:31
EGLSurface surface
Definition: eglext.h:74
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void)
Definition: SDL_cpuinfo.c:548
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
DECLSPEC int SDLCALL SDL_sscanf(const char *text, const char *fmt,...)
Definition: SDL_string.c:1011
int dst_pitch
Definition: SDL_blit.h:63
DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void)
Definition: SDL_cpuinfo.c:566
int dst_skip
Definition: SDL_blit.h:64
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
Definition: SDL_rect.h:72
#define SDL_COPY_ADD
Definition: SDL_blit.h:37
Uint32 flags
Definition: SDL_surface.h:71
#define SDL_COPY_RLE_DESIRED
Definition: SDL_blit.h:41
void SDL_InvalidateMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:972
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
#define SDL_COPY_NEAREST
Definition: SDL_blit.h:40
DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface)
Definition: SDL_surface.c:786
Uint8 * dst
Definition: SDL_blit.h:61
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
void SDL_BlitCopy(SDL_BlitInfo *info)
Definition: SDL_blit_copy.c:91
GLuint64EXT * result
Definition: glew.h:12708
int cpu
Definition: SDL_blit.h:80
GLenum GLenum dst
Definition: glew.h:2396
static SDL_BlitFunc SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, SDL_BlitFuncEntry *entries)
Definition: SDL_blit.c:128
new_palette entries
Definition: pngrutil.c:1486
void * pixels
Definition: SDL_surface.h:75
Uint8 BitsPerPixel
Definition: SDL_pixels.h:276
#define SDL_CPU_ALTIVEC_PREFETCH
Definition: SDL_blit.h:52
DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void)
Definition: SDL_cpuinfo.c:557
#define SDL_CPU_3DNOW
Definition: SDL_blit.h:49
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
int x
Definition: SDL_rect.h:65
Uint8 * src
Definition: SDL_blit.h:57
int w
Definition: SDL_rect.h:66
int SDL_CalculateBlit(SDL_Surface *surface)
Definition: SDL_blit.c:216
Definition: SDL_blit.h:75
SDL_PixelFormat * dst_fmt
Definition: SDL_blit.h:66
SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[]
int src_pitch
Definition: SDL_blit.h:59
int SDL_RLESurface(SDL_Surface *surface)
SDL_Surface * dst
Definition: SDL_blit.h:87
#define SDL_CPU_SSE2
Definition: SDL_blit.h:51
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface)
Definition: SDL_blit_0.c:454
DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void)
Definition: SDL_cpuinfo.c:539
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
int h
Definition: SDL_rect.h:66
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface)
Definition: SDL_blit_1.c:520
#define SDL_CPU_SSE
Definition: SDL_blit.h:50
static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_blit.c:34
void * data
Definition: SDL_blit.h:90
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
#define SDL_CPU_ANY
Definition: SDL_blit.h:47
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:143
GLenum src
Definition: glew.h:2396
int i
Definition: pngrutil.c:1377
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint GLint j2 GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLint *params GLenum GLenum GLfloat *params GLenum GLint GLenum GLenum GLvoid *pixels GLenum GLint GLenum GLint *params GLenum GLenum GLint *params GLenum GLsizei const GLvoid *pointer GLenum GLenum const GLint *params GLenum GLfloat GLfloat GLint GLint const GLfloat *points GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat *points GLint GLfloat GLfloat GLint GLfloat GLfloat v2 GLenum GLenum const GLint *params GLdouble GLdouble GLdouble GLdouble GLdouble GLdouble zFar GLenum map
Definition: SDL_glfuncs.h:268
SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface)
Definition: SDL_blit_A.c:1271
static SDL_bool SDL_UseAltivecPrefetch()
Definition: SDL_blit.c:120
int identity
Definition: SDL_blit.h:88
DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
Definition: SDL_surface.c:765
int y
Definition: SDL_rect.h:65
#define SDL_CPU_ALTIVEC_NOPREFETCH
Definition: SDL_blit.h:53
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_BlitInfo info
Definition: SDL_blit.h:91
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
#define SDL_RLEACCEL
Definition: SDL_surface.h:54