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

Latest commit

 

History

History
240 lines (213 loc) · 6.82 KB

SDL_blit.c

File metadata and controls

240 lines (213 loc) · 6.82 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 16, 2007
Aug 16, 2007
27
#include "SDL_blit_copy.h"
Apr 26, 2001
Apr 26, 2001
28
29
30
31
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
/* The general purpose software blit routine */
Jul 10, 2006
Jul 10, 2006
32
33
34
static int
SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
Apr 26, 2001
Apr 26, 2001
35
{
Jul 10, 2006
Jul 10, 2006
36
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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) {
SDL_BlitInfo info;
SDL_loblit RunBlit;
/* Set up the blit information */
info.s_pixels = (Uint8 *) src->pixels +
(Uint16) srcrect->y * src->pitch +
(Uint16) srcrect->x * src->format->BytesPerPixel;
info.s_width = srcrect->w;
info.s_height = srcrect->h;
info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
info.d_pixels = (Uint8 *) dst->pixels +
(Uint16) dstrect->y * dst->pitch +
(Uint16) dstrect->x * dst->format->BytesPerPixel;
info.d_width = dstrect->w;
info.d_height = dstrect->h;
info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
info.src = src->format;
info.table = src->map->table;
info.dst = dst->format;
Aug 17, 2007
Aug 17, 2007
83
84
info.ckey = src->map->ckey;
info.cmod = src->map->cmod;
Aug 17, 2007
Aug 17, 2007
85
RunBlit = (SDL_loblit) src->map->data;
Jul 10, 2006
Jul 10, 2006
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/* Run the actual software blit */
RunBlit(&info);
}
/* 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
}
Aug 15, 2007
Aug 15, 2007
102
103
#ifdef __MACOSX__
#include <sys/sysctl.h>
Aug 22, 2003
Aug 22, 2003
104
Aug 16, 2007
Aug 16, 2007
105
106
static SDL_bool
SDL_UseAltivecPrefetch()
Aug 22, 2003
Aug 22, 2003
107
{
Aug 15, 2007
Aug 15, 2007
108
109
110
const char key[] = "hw.l3cachesize";
u_int64_t result = 0;
size_t typeSize = sizeof(result);
Jul 10, 2006
Jul 10, 2006
111
Aug 15, 2007
Aug 15, 2007
112
113
114
115
if (sysctlbyname(key, &result, &typeSize, NULL, 0) == 0 && result > 0) {
return SDL_TRUE;
} else {
return SDL_FALSE;
Jul 10, 2006
Jul 10, 2006
116
}
Aug 22, 2003
Aug 22, 2003
117
}
Aug 15, 2007
Aug 15, 2007
118
#else
Aug 16, 2007
Aug 16, 2007
119
120
static SDL_bool
SDL_UseAltivecPrefetch()
Apr 26, 2001
Apr 26, 2001
121
{
Aug 15, 2007
Aug 15, 2007
122
123
/* Just guess G4 */
return SDL_TRUE;
Apr 26, 2001
Apr 26, 2001
124
}
Aug 15, 2007
Aug 15, 2007
125
#endif /* __MACOSX__ */
Apr 26, 2001
Apr 26, 2001
126
Aug 16, 2007
Aug 16, 2007
127
128
static SDL_loblit
SDL_ChooseBlitFunc(SDL_BlitEntry * entries, int count)
Apr 26, 2001
Apr 26, 2001
129
{
Aug 15, 2007
Aug 15, 2007
130
131
132
133
int i;
static Uint32 features = 0xffffffff;
if (features == 0xffffffff) {
Aug 16, 2007
Aug 16, 2007
134
135
const char *override = SDL_getenv("SDL_BLIT_FEATURES");
Aug 15, 2007
Aug 15, 2007
136
features = SDL_BLIT_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
143
144
145
146
147
if (override) {
SDL_sscanf(override, "%u", &features);
} else {
if (SDL_HasMMX()) {
features |= SDL_BLIT_MMX;
}
if (SDL_HasSSE()) {
features |= SDL_BLIT_SSE;
}
Aug 16, 2007
Aug 16, 2007
148
if (SDL_HasAltiVec()) {
Aug 15, 2007
Aug 15, 2007
149
150
151
152
153
154
if (SDL_UseAltivecPrefetch()) {
features |= SDL_BLIT_ALTIVEC_PREFETCH;
} else {
features |= SDL_BLIT_ALTIVEC_NOPREFETCH;
}
}
Jul 10, 2006
Jul 10, 2006
155
}
Aug 15, 2007
Aug 15, 2007
156
157
158
159
160
}
for (i = count; i > 0; --i) {
if (features & entries[i].features) {
return entries[i].blit;
Jul 10, 2006
Jul 10, 2006
161
162
}
}
Aug 15, 2007
Aug 15, 2007
163
return entries[0].blit;
Apr 26, 2001
Apr 26, 2001
164
165
166
}
/* Figure out which of many blit routines to set up on a surface */
Jul 10, 2006
Jul 10, 2006
167
168
int
SDL_CalculateBlit(SDL_Surface * surface)
Apr 26, 2001
Apr 26, 2001
169
{
Aug 17, 2007
Aug 17, 2007
170
SDL_loblit blit = NULL;
Jul 10, 2006
Jul 10, 2006
171
172
173
174
175
176
int blit_index;
/* Clean everything out to start */
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
SDL_UnRLESurface(surface, 1);
}
Aug 17, 2007
Aug 17, 2007
177
surface->map->blit = NULL;
Jul 10, 2006
Jul 10, 2006
178
179
180
181
182
183
/* Get the blit function index, based on surface mode */
/* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */
blit_index = 0;
blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0;
if (surface->flags & SDL_SRCALPHA
Aug 17, 2007
Aug 17, 2007
184
&& ((surface->map->cmod >> 24) != SDL_ALPHA_OPAQUE
Jul 10, 2006
Jul 10, 2006
185
186
187
188
189
190
191
192
|| surface->format->Amask)) {
blit_index |= 2;
}
/* Check for special "identity" case -- copy blit */
if (surface->map->identity && blit_index == 0) {
/* Handle overlapping blits on the same surface */
if (surface == surface->map->dst) {
Aug 17, 2007
Aug 17, 2007
193
blit = SDL_BlitCopyOverlap;
Aug 15, 2007
Aug 15, 2007
194
} else {
Aug 17, 2007
Aug 17, 2007
195
blit = SDL_BlitCopy;
Jul 10, 2006
Jul 10, 2006
196
197
198
}
} else {
if (surface->format->BitsPerPixel < 8) {
Aug 17, 2007
Aug 17, 2007
199
blit = SDL_CalculateBlit0(surface, blit_index);
Jul 10, 2006
Jul 10, 2006
200
201
202
} else {
switch (surface->format->BytesPerPixel) {
case 1:
Aug 17, 2007
Aug 17, 2007
203
blit = SDL_CalculateBlit1(surface, blit_index);
Jul 10, 2006
Jul 10, 2006
204
205
206
207
break;
case 2:
case 3:
case 4:
Aug 17, 2007
Aug 17, 2007
208
blit = SDL_CalculateBlitN(surface, blit_index);
Jul 10, 2006
Jul 10, 2006
209
210
211
212
213
break;
}
}
}
/* Make sure we have a blit function */
Aug 17, 2007
Aug 17, 2007
214
if (blit == NULL) {
Jul 10, 2006
Jul 10, 2006
215
216
217
218
219
220
221
222
223
224
225
SDL_InvalidateMap(surface->map);
SDL_SetError("Blit combination not supported");
return (-1);
}
/* Choose software blitting function */
if (surface->flags & SDL_RLEACCELOK) {
if (surface->map->identity
&& (blit_index == 1
|| (blit_index == 3 && !surface->format->Amask))) {
if (SDL_RLESurface(surface) == 0)
Aug 17, 2007
Aug 17, 2007
226
surface->map->blit = SDL_RLEBlit;
Jul 10, 2006
Jul 10, 2006
227
228
} else if (blit_index == 2 && surface->format->Amask) {
if (SDL_RLESurface(surface) == 0)
Aug 17, 2007
Aug 17, 2007
229
surface->map->blit = SDL_RLEAlphaBlit;
Jul 10, 2006
Jul 10, 2006
230
231
232
}
}
Aug 17, 2007
Aug 17, 2007
233
234
235
if (surface->map->blit == NULL) {
surface->map->blit = SDL_SoftBlit;
surface->map->data = blit;
Jul 10, 2006
Jul 10, 2006
236
237
}
return (0);
Apr 26, 2001
Apr 26, 2001
238
239
}
Jul 10, 2006
Jul 10, 2006
240
/* vi: set ts=4 sw=4 expandtab: */