Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Latest commit

 

History

History
280 lines (247 loc) · 7.89 KB

SDL_blit.c

File metadata and controls

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