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

Latest commit

 

History

History
296 lines (262 loc) · 8.56 KB

SDL_blit.c

File metadata and controls

296 lines (262 loc) · 8.56 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Dec 8, 2008
Dec 8, 2008
3
Copyright (C) 1997-2009 Sam Lantinga
Apr 26, 2001
Apr 26, 2001
4
5
This library is free software; you can redistribute it and/or
Feb 1, 2006
Feb 1, 2006
6
modify it under the terms of the GNU Lesser General Public
Apr 26, 2001
Apr 26, 2001
7
License as published by the Free Software Foundation; either
Feb 1, 2006
Feb 1, 2006
8
version 2.1 of the License, or (at your option) any later version.
Apr 26, 2001
Apr 26, 2001
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Feb 1, 2006
Feb 1, 2006
13
Lesser General Public License for more details.
Apr 26, 2001
Apr 26, 2001
14
Feb 1, 2006
Feb 1, 2006
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Apr 26, 2001
Apr 26, 2001
18
19
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Apr 26, 2001
Apr 26, 2001
21
*/
Feb 21, 2006
Feb 21, 2006
22
#include "SDL_config.h"
Apr 26, 2001
Apr 26, 2001
23
24
25
26
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_blit.h"
Aug 17, 2007
Aug 17, 2007
27
#include "SDL_blit_auto.h"
Aug 16, 2007
Aug 16, 2007
28
#include "SDL_blit_copy.h"
Dec 2, 2008
Dec 2, 2008
29
#include "SDL_blit_slow.h"
Apr 26, 2001
Apr 26, 2001
30
31
32
33
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
/* The general purpose software blit routine */
Jul 10, 2006
Jul 10, 2006
34
35
36
static int
SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
Apr 26, 2001
Apr 26, 2001
37
{
Jul 10, 2006
Jul 10, 2006
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
65
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
66
SDL_BlitFunc RunBlit;
Aug 17, 2007
Aug 17, 2007
67
SDL_BlitInfo *info = &src->map->info;
Jul 10, 2006
Jul 10, 2006
68
69
/* Set up the blit information */
Aug 17, 2007
Aug 17, 2007
70
info->src = (Uint8 *) src->pixels +
Jul 10, 2006
Jul 10, 2006
71
(Uint16) srcrect->y * src->pitch +
Aug 17, 2007
Aug 17, 2007
72
(Uint16) srcrect->x * info->src_fmt->BytesPerPixel;
Aug 17, 2007
Aug 17, 2007
73
74
info->src_w = srcrect->w;
info->src_h = srcrect->h;
Dec 7, 2008
Dec 7, 2008
75
info->src_pitch = src->pitch;
Aug 18, 2007
Aug 18, 2007
76
77
78
79
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
80
(Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
Aug 17, 2007
Aug 17, 2007
81
82
info->dst_w = dstrect->w;
info->dst_h = dstrect->h;
Dec 7, 2008
Dec 7, 2008
83
info->dst_pitch = dst->pitch;
Aug 18, 2007
Aug 18, 2007
84
85
info->dst_skip =
info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel;
Aug 17, 2007
Aug 17, 2007
86
RunBlit = (SDL_BlitFunc) src->map->data;
Jul 10, 2006
Jul 10, 2006
87
88
/* Run the actual software blit */
Aug 17, 2007
Aug 17, 2007
89
RunBlit(info);
Jul 10, 2006
Jul 10, 2006
90
91
92
93
94
95
96
97
98
99
100
}
/* 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
101
102
}
Aug 15, 2007
Aug 15, 2007
103
104
#ifdef __MACOSX__
#include <sys/sysctl.h>
Aug 22, 2003
Aug 22, 2003
105
Aug 16, 2007
Aug 16, 2007
106
107
static SDL_bool
SDL_UseAltivecPrefetch()
Aug 22, 2003
Aug 22, 2003
108
{
Aug 15, 2007
Aug 15, 2007
109
110
111
const char key[] = "hw.l3cachesize";
u_int64_t result = 0;
size_t typeSize = sizeof(result);
Jul 10, 2006
Jul 10, 2006
112
Aug 15, 2007
Aug 15, 2007
113
114
115
116
if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) {
return SDL_TRUE;
} else {
return SDL_FALSE;
Jul 10, 2006
Jul 10, 2006
117
}
Aug 22, 2003
Aug 22, 2003
118
}
Aug 15, 2007
Aug 15, 2007
119
#else
Aug 16, 2007
Aug 16, 2007
120
121
static SDL_bool
SDL_UseAltivecPrefetch()
Apr 26, 2001
Apr 26, 2001
122
{
Aug 15, 2007
Aug 15, 2007
123
124
/* Just guess G4 */
return SDL_TRUE;
Apr 26, 2001
Apr 26, 2001
125
}
Aug 15, 2007
Aug 15, 2007
126
#endif /* __MACOSX__ */
Apr 26, 2001
Apr 26, 2001
127
Aug 17, 2007
Aug 17, 2007
128
static SDL_BlitFunc
Aug 18, 2007
Aug 18, 2007
129
130
SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
SDL_BlitFuncEntry * entries)
Apr 26, 2001
Apr 26, 2001
131
{
Aug 17, 2007
Aug 17, 2007
132
int i, flagcheck;
Aug 15, 2007
Aug 15, 2007
133
134
static Uint32 features = 0xffffffff;
Aug 17, 2007
Aug 17, 2007
135
/* Get the available CPU features */
Aug 15, 2007
Aug 15, 2007
136
if (features == 0xffffffff) {
Aug 17, 2007
Aug 17, 2007
137
const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");
Aug 16, 2007
Aug 16, 2007
138
Aug 17, 2007
Aug 17, 2007
139
features = SDL_CPU_ANY;
Jul 10, 2006
Jul 10, 2006
140
Aug 16, 2007
Aug 16, 2007
141
/* Allow an override for testing .. */
Aug 15, 2007
Aug 15, 2007
142
143
144
145
if (override) {
SDL_sscanf(override, "%u", &features);
} else {
if (SDL_HasMMX()) {
Aug 17, 2007
Aug 17, 2007
146
147
148
149
features |= SDL_CPU_MMX;
}
if (SDL_Has3DNow()) {
features |= SDL_CPU_3DNOW;
Aug 15, 2007
Aug 15, 2007
150
151
}
if (SDL_HasSSE()) {
Aug 17, 2007
Aug 17, 2007
152
153
154
155
features |= SDL_CPU_SSE;
}
if (SDL_HasSSE2()) {
features |= SDL_CPU_SSE2;
Aug 15, 2007
Aug 15, 2007
156
}
Aug 16, 2007
Aug 16, 2007
157
if (SDL_HasAltiVec()) {
Aug 15, 2007
Aug 15, 2007
158
if (SDL_UseAltivecPrefetch()) {
Aug 17, 2007
Aug 17, 2007
159
features |= SDL_CPU_ALTIVEC_PREFETCH;
Aug 15, 2007
Aug 15, 2007
160
} else {
Aug 17, 2007
Aug 17, 2007
161
features |= SDL_CPU_ALTIVEC_NOPREFETCH;
Aug 15, 2007
Aug 15, 2007
162
163
}
}
Jul 10, 2006
Jul 10, 2006
164
}
Aug 15, 2007
Aug 15, 2007
165
166
}
Aug 17, 2007
Aug 17, 2007
167
for (i = 0; entries[i].func; ++i) {
Aug 17, 2007
Aug 17, 2007
168
/* Check for matching pixel formats */
Aug 17, 2007
Aug 17, 2007
169
170
171
172
173
174
if (src_format != entries[i].src_format) {
continue;
}
if (dst_format != entries[i].dst_format) {
continue;
}
Aug 17, 2007
Aug 17, 2007
175
176
/* Check modulation flags */
Aug 18, 2007
Aug 18, 2007
177
flagcheck =
Dec 6, 2008
Dec 6, 2008
178
(flags & (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA));
Aug 17, 2007
Aug 17, 2007
179
180
181
182
183
if ((flagcheck & entries[i].flags) != flagcheck) {
continue;
}
/* Check blend flags */
Aug 18, 2007
Aug 18, 2007
184
185
186
flagcheck =
(flags &
(SDL_COPY_MASK | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD));
Aug 17, 2007
Aug 17, 2007
187
188
189
190
191
192
193
194
195
196
197
198
199
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
200
continue;
Jul 10, 2006
Jul 10, 2006
201
}
Aug 17, 2007
Aug 17, 2007
202
203
204
205
/* Check CPU features */
flagcheck = entries[i].cpu;
if ((flagcheck & features) != flagcheck) {
Aug 17, 2007
Aug 17, 2007
206
207
continue;
}
Aug 17, 2007
Aug 17, 2007
208
209
/* We found the best one! */
Aug 17, 2007
Aug 17, 2007
210
return entries[i].func;
Jul 10, 2006
Jul 10, 2006
211
}
Aug 17, 2007
Aug 17, 2007
212
return NULL;
Apr 26, 2001
Apr 26, 2001
213
214
215
}
/* Figure out which of many blit routines to set up on a surface */
Jul 10, 2006
Jul 10, 2006
216
217
int
SDL_CalculateBlit(SDL_Surface * surface)
Apr 26, 2001
Apr 26, 2001
218
{
Aug 17, 2007
Aug 17, 2007
219
SDL_BlitFunc blit = NULL;
Aug 18, 2007
Aug 18, 2007
220
221
SDL_BlitMap *map = surface->map;
SDL_Surface *dst = map->dst;
Jul 10, 2006
Jul 10, 2006
222
223
224
225
226
/* Clean everything out to start */
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
SDL_UnRLESurface(surface, 1);
}
Aug 18, 2007
Aug 18, 2007
227
228
229
230
231
232
233
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
234
if (map->info.flags & SDL_COPY_RLE_DESIRED) {
Aug 18, 2007
Aug 18, 2007
235
236
237
238
if (SDL_RLESurface(surface) == 0) {
return 0;
}
}
Jul 10, 2006
Jul 10, 2006
239
Aug 18, 2007
Aug 18, 2007
240
/* Choose a standard blit function */
Nov 29, 2008
Nov 29, 2008
241
if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) {
Jul 10, 2006
Jul 10, 2006
242
/* Handle overlapping blits on the same surface */
Aug 17, 2007
Aug 17, 2007
243
if (surface == dst) {
Aug 17, 2007
Aug 17, 2007
244
blit = SDL_BlitCopyOverlap;
Aug 15, 2007
Aug 15, 2007
245
} else {
Aug 17, 2007
Aug 17, 2007
246
blit = SDL_BlitCopy;
Jul 10, 2006
Jul 10, 2006
247
}
Aug 18, 2007
Aug 18, 2007
248
} else if (surface->format->BitsPerPixel < 8) {
Aug 18, 2007
Aug 18, 2007
249
blit = SDL_CalculateBlit0(surface);
Aug 18, 2007
Aug 18, 2007
250
} else if (surface->format->BytesPerPixel == 1) {
Aug 18, 2007
Aug 18, 2007
251
252
253
blit = SDL_CalculateBlit1(surface);
} else if (map->info.flags & SDL_COPY_BLEND) {
blit = SDL_CalculateBlitA(surface);
Jul 10, 2006
Jul 10, 2006
254
} else {
Aug 18, 2007
Aug 18, 2007
255
blit = SDL_CalculateBlitN(surface);
Jul 10, 2006
Jul 10, 2006
256
}
Aug 17, 2007
Aug 17, 2007
257
if (blit == NULL) {
Aug 18, 2007
Aug 18, 2007
258
259
260
261
262
263
264
265
Uint32 src_format =
SDL_MasksToPixelFormatEnum(surface->format->BitsPerPixel,
surface->format->Rmask,
surface->format->Gmask,
surface->format->Bmask,
surface->format->Amask);
Uint32 dst_format =
SDL_MasksToPixelFormatEnum(dst->format->BitsPerPixel,
Mar 14, 2008
Mar 14, 2008
266
dst->format->Rmask,
Mar 14, 2008
Mar 14, 2008
267
dst->format->Gmask,
Aug 18, 2007
Aug 18, 2007
268
269
270
271
272
273
dst->format->Bmask,
dst->format->Amask);
blit =
SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
SDL_GeneratedBlitFuncTable);
Aug 17, 2007
Aug 17, 2007
274
}
Dec 2, 2008
Dec 2, 2008
275
276
277
278
279
280
281
282
283
#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
284
map->data = blit;
Aug 17, 2007
Aug 17, 2007
285
Jul 10, 2006
Jul 10, 2006
286
/* Make sure we have a blit function */
Aug 17, 2007
Aug 17, 2007
287
if (blit == NULL) {
Aug 18, 2007
Aug 18, 2007
288
SDL_InvalidateMap(map);
Jul 10, 2006
Jul 10, 2006
289
290
291
292
293
SDL_SetError("Blit combination not supported");
return (-1);
}
return (0);
Apr 26, 2001
Apr 26, 2001
294
295
}
Jul 10, 2006
Jul 10, 2006
296
/* vi: set ts=4 sw=4 expandtab: */