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

Latest commit

 

History

History
285 lines (251 loc) · 8.31 KB

SDL_blit.c

File metadata and controls

285 lines (251 loc) · 8.31 KB
 
Apr 26, 2001
Apr 26, 2001
1
2
/*
SDL - Simple DirectMedia Layer
Feb 1, 2006
Feb 1, 2006
3
Copyright (C) 1997-2006 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"
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;
Aug 18, 2007
Aug 18, 2007
74
75
76
77
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
78
(Uint16) dstrect->x * info->dst_fmt->BytesPerPixel;
Aug 17, 2007
Aug 17, 2007
79
80
info->dst_w = dstrect->w;
info->dst_h = dstrect->h;
Aug 18, 2007
Aug 18, 2007
81
82
info->dst_skip =
info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel;
Aug 17, 2007
Aug 17, 2007
83
RunBlit = (SDL_BlitFunc) src->map->data;
Jul 10, 2006
Jul 10, 2006
84
85
/* Run the actual software blit */
Aug 17, 2007
Aug 17, 2007
86
RunBlit(info);
Jul 10, 2006
Jul 10, 2006
87
88
89
90
91
92
93
94
95
96
97
}
/* 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
98
99
}
Aug 15, 2007
Aug 15, 2007
100
101
#ifdef __MACOSX__
#include <sys/sysctl.h>
Aug 22, 2003
Aug 22, 2003
102
Aug 16, 2007
Aug 16, 2007
103
104
static SDL_bool
SDL_UseAltivecPrefetch()
Aug 22, 2003
Aug 22, 2003
105
{
Aug 15, 2007
Aug 15, 2007
106
107
108
const char key[] = "hw.l3cachesize";
u_int64_t result = 0;
size_t typeSize = sizeof(result);
Jul 10, 2006
Jul 10, 2006
109
Aug 15, 2007
Aug 15, 2007
110
111
112
113
if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) {
return SDL_TRUE;
} else {
return SDL_FALSE;
Jul 10, 2006
Jul 10, 2006
114
}
Aug 22, 2003
Aug 22, 2003
115
}
Aug 15, 2007
Aug 15, 2007
116
#else
Aug 16, 2007
Aug 16, 2007
117
118
static SDL_bool
SDL_UseAltivecPrefetch()
Apr 26, 2001
Apr 26, 2001
119
{
Aug 15, 2007
Aug 15, 2007
120
121
/* Just guess G4 */
return SDL_TRUE;
Apr 26, 2001
Apr 26, 2001
122
}
Aug 15, 2007
Aug 15, 2007
123
#endif /* __MACOSX__ */
Apr 26, 2001
Apr 26, 2001
124
Aug 17, 2007
Aug 17, 2007
125
static SDL_BlitFunc
Aug 18, 2007
Aug 18, 2007
126
127
SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
SDL_BlitFuncEntry * entries)
Apr 26, 2001
Apr 26, 2001
128
{
Aug 17, 2007
Aug 17, 2007
129
int i, flagcheck;
Aug 15, 2007
Aug 15, 2007
130
131
static Uint32 features = 0xffffffff;
Aug 17, 2007
Aug 17, 2007
132
/* Get the available CPU features */
Aug 15, 2007
Aug 15, 2007
133
if (features == 0xffffffff) {
Aug 17, 2007
Aug 17, 2007
134
const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");
Aug 16, 2007
Aug 16, 2007
135
Aug 17, 2007
Aug 17, 2007
136
features = SDL_CPU_ANY;
Jul 10, 2006
Jul 10, 2006
137
Aug 16, 2007
Aug 16, 2007
138
/* Allow an override for testing .. */
Aug 15, 2007
Aug 15, 2007
139
140
141
142
if (override) {
SDL_sscanf(override, "%u", &features);
} else {
if (SDL_HasMMX()) {
Aug 17, 2007
Aug 17, 2007
143
144
145
146
features |= SDL_CPU_MMX;
}
if (SDL_Has3DNow()) {
features |= SDL_CPU_3DNOW;
Aug 15, 2007
Aug 15, 2007
147
148
}
if (SDL_HasSSE()) {
Aug 17, 2007
Aug 17, 2007
149
150
151
152
features |= SDL_CPU_SSE;
}
if (SDL_HasSSE2()) {
features |= SDL_CPU_SSE2;
Aug 15, 2007
Aug 15, 2007
153
}
Aug 16, 2007
Aug 16, 2007
154
if (SDL_HasAltiVec()) {
Aug 15, 2007
Aug 15, 2007
155
if (SDL_UseAltivecPrefetch()) {
Aug 17, 2007
Aug 17, 2007
156
features |= SDL_CPU_ALTIVEC_PREFETCH;
Aug 15, 2007
Aug 15, 2007
157
} else {
Aug 17, 2007
Aug 17, 2007
158
features |= SDL_CPU_ALTIVEC_NOPREFETCH;
Aug 15, 2007
Aug 15, 2007
159
160
}
}
Jul 10, 2006
Jul 10, 2006
161
}
Aug 15, 2007
Aug 15, 2007
162
163
}
Aug 17, 2007
Aug 17, 2007
164
for (i = 0; entries[i].func; ++i) {
Aug 17, 2007
Aug 17, 2007
165
/* Check for matching pixel formats */
Aug 17, 2007
Aug 17, 2007
166
167
168
169
170
171
if (src_format != entries[i].src_format) {
continue;
}
if (dst_format != entries[i].dst_format) {
continue;
}
Aug 17, 2007
Aug 17, 2007
172
173
/* Check modulation flags */
Aug 18, 2007
Aug 18, 2007
174
175
flagcheck =
(flags & (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_COLOR));
Aug 17, 2007
Aug 17, 2007
176
177
178
179
180
if ((flagcheck & entries[i].flags) != flagcheck) {
continue;
}
/* Check blend flags */
Aug 18, 2007
Aug 18, 2007
181
182
183
flagcheck =
(flags &
(SDL_COPY_MASK | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD));
Aug 17, 2007
Aug 17, 2007
184
185
186
187
188
189
190
191
192
193
194
195
196
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
197
continue;
Jul 10, 2006
Jul 10, 2006
198
}
Aug 17, 2007
Aug 17, 2007
199
200
201
202
/* Check CPU features */
flagcheck = entries[i].cpu;
if ((flagcheck & features) != flagcheck) {
Aug 17, 2007
Aug 17, 2007
203
204
continue;
}
Aug 17, 2007
Aug 17, 2007
205
206
/* We found the best one! */
Aug 17, 2007
Aug 17, 2007
207
return entries[i].func;
Jul 10, 2006
Jul 10, 2006
208
}
Aug 17, 2007
Aug 17, 2007
209
return NULL;
Apr 26, 2001
Apr 26, 2001
210
211
212
}
/* Figure out which of many blit routines to set up on a surface */
Jul 10, 2006
Jul 10, 2006
213
214
int
SDL_CalculateBlit(SDL_Surface * surface)
Apr 26, 2001
Apr 26, 2001
215
{
Aug 17, 2007
Aug 17, 2007
216
SDL_BlitFunc blit = NULL;
Aug 18, 2007
Aug 18, 2007
217
218
SDL_BlitMap *map = surface->map;
SDL_Surface *dst = map->dst;
Jul 10, 2006
Jul 10, 2006
219
220
221
222
223
/* Clean everything out to start */
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
SDL_UnRLESurface(surface, 1);
}
Aug 18, 2007
Aug 18, 2007
224
225
226
227
228
229
230
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 */
Aug 18, 2007
Aug 18, 2007
231
if (surface->map->info.flags & SDL_COPY_RLE_DESIRED) {
Aug 18, 2007
Aug 18, 2007
232
if (SDL_RLESurface(surface) == 0) {
Mar 14, 2008
Mar 14, 2008
233
surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED;
Aug 18, 2007
Aug 18, 2007
234
235
236
return 0;
}
}
Jul 10, 2006
Jul 10, 2006
237
Aug 18, 2007
Aug 18, 2007
238
239
/* Choose a standard blit function */
if (map->identity && !map->info.flags) {
Jul 10, 2006
Jul 10, 2006
240
/* Handle overlapping blits on the same surface */
Aug 17, 2007
Aug 17, 2007
241
if (surface == dst) {
Aug 17, 2007
Aug 17, 2007
242
blit = SDL_BlitCopyOverlap;
Aug 15, 2007
Aug 15, 2007
243
} else {
Aug 17, 2007
Aug 17, 2007
244
blit = SDL_BlitCopy;
Jul 10, 2006
Jul 10, 2006
245
}
Aug 18, 2007
Aug 18, 2007
246
} else if (surface->format->BitsPerPixel < 8) {
Aug 18, 2007
Aug 18, 2007
247
blit = SDL_CalculateBlit0(surface);
Aug 18, 2007
Aug 18, 2007
248
} else if (surface->format->BytesPerPixel == 1) {
Aug 18, 2007
Aug 18, 2007
249
250
251
blit = SDL_CalculateBlit1(surface);
} else if (map->info.flags & SDL_COPY_BLEND) {
blit = SDL_CalculateBlitA(surface);
Jul 10, 2006
Jul 10, 2006
252
} else {
Aug 18, 2007
Aug 18, 2007
253
blit = SDL_CalculateBlitN(surface);
Jul 10, 2006
Jul 10, 2006
254
}
Aug 17, 2007
Aug 17, 2007
255
if (blit == NULL) {
Aug 18, 2007
Aug 18, 2007
256
257
258
259
260
261
262
263
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
264
dst->format->Rmask,
Mar 14, 2008
Mar 14, 2008
265
dst->format->Gmask,
Aug 18, 2007
Aug 18, 2007
266
267
268
269
270
271
dst->format->Bmask,
dst->format->Amask);
blit =
SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags,
SDL_GeneratedBlitFuncTable);
Aug 17, 2007
Aug 17, 2007
272
}
Aug 18, 2007
Aug 18, 2007
273
map->data = blit;
Aug 17, 2007
Aug 17, 2007
274
Jul 10, 2006
Jul 10, 2006
275
/* Make sure we have a blit function */
Aug 17, 2007
Aug 17, 2007
276
if (blit == NULL) {
Aug 18, 2007
Aug 18, 2007
277
SDL_InvalidateMap(map);
Jul 10, 2006
Jul 10, 2006
278
279
280
281
282
SDL_SetError("Blit combination not supported");
return (-1);
}
return (0);
Apr 26, 2001
Apr 26, 2001
283
284
}
Jul 10, 2006
Jul 10, 2006
285
/* vi: set ts=4 sw=4 expandtab: */