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

Latest commit

 

History

History
294 lines (263 loc) · 8.28 KB

SDL_blit.c

File metadata and controls

294 lines (263 loc) · 8.28 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
27
28
29
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_blit.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
Feb 21, 2006
Feb 21, 2006
30
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && SDL_ASSEMBLY_ROUTINES
Apr 11, 2004
Apr 11, 2004
31
32
33
34
#define MMX_ASMBLIT
#endif
#if defined(MMX_ASMBLIT)
Nov 18, 2003
Nov 18, 2003
35
#include "SDL_cpuinfo.h"
Aug 22, 2003
Aug 22, 2003
36
37
38
#include "mmx.h"
#endif
Apr 26, 2001
Apr 26, 2001
39
/* The general purpose software blit routine */
May 28, 2006
May 28, 2006
40
static int
May 29, 2006
May 29, 2006
41
42
SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect,
SDL_Surface * dst, SDL_Rect * dstrect)
Apr 26, 2001
Apr 26, 2001
43
{
May 28, 2006
May 28, 2006
44
45
46
47
48
49
50
51
52
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;
May 29, 2006
May 29, 2006
53
54
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
May 28, 2006
May 28, 2006
55
56
57
58
59
60
61
okay = 0;
} else {
dst_locked = 1;
}
}
/* Lock the source if it's in hardware */
src_locked = 0;
May 29, 2006
May 29, 2006
62
63
if (SDL_MUSTLOCK(src)) {
if (SDL_LockSurface(src) < 0) {
May 28, 2006
May 28, 2006
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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.aux_data = src->map->sw_data->aux_data;
info.src = src->format;
info.table = src->map->table;
info.dst = dst->format;
RunBlit = src->map->sw_data->blit;
/* Run the actual software blit */
May 29, 2006
May 29, 2006
95
RunBlit(&info);
May 28, 2006
May 28, 2006
96
97
98
99
}
/* We need to unlock the surfaces if they're locked */
if (dst_locked) {
May 29, 2006
May 29, 2006
100
SDL_UnlockSurface(dst);
May 28, 2006
May 28, 2006
101
102
}
if (src_locked) {
May 29, 2006
May 29, 2006
103
SDL_UnlockSurface(src);
May 28, 2006
May 28, 2006
104
105
106
}
/* Blit is done! */
return (okay ? 0 : -1);
Apr 26, 2001
Apr 26, 2001
107
108
}
Apr 11, 2004
Apr 11, 2004
109
#ifdef MMX_ASMBLIT
May 28, 2006
May 28, 2006
110
static __inline__ void
May 29, 2006
May 29, 2006
111
SDL_memcpyMMX(Uint8 * to, const Uint8 * from, int len)
Aug 22, 2003
Aug 22, 2003
112
{
May 28, 2006
May 28, 2006
113
114
115
int i;
for (i = 0; i < len / 8; i++) {
May 29, 2006
May 29, 2006
116
117
118
__asm__ __volatile__(" movq (%0), %%mm0\n"
" movq %%mm0, (%1)\n"::"r"(from),
"r"(to):"memory");
May 28, 2006
May 28, 2006
119
120
121
122
from += 8;
to += 8;
}
if (len & 7)
May 29, 2006
May 29, 2006
123
SDL_memcpy(to, from, len & 7);
Aug 22, 2003
Aug 22, 2003
124
125
}
May 28, 2006
May 28, 2006
126
static __inline__ void
May 29, 2006
May 29, 2006
127
SDL_memcpySSE(Uint8 * to, const Uint8 * from, int len)
Aug 22, 2003
Aug 22, 2003
128
{
May 28, 2006
May 28, 2006
129
130
int i;
May 29, 2006
May 29, 2006
131
132
133
134
__asm__ __volatile__(" prefetchnta (%0)\n"
" prefetchnta 64(%0)\n"
" prefetchnta 128(%0)\n"
" prefetchnta 192(%0)\n"::"r"(from));
May 28, 2006
May 28, 2006
135
136
for (i = 0; i < len / 8; i++) {
May 29, 2006
May 29, 2006
137
138
139
140
__asm__ __volatile__(" prefetchnta 256(%0)\n"
" movq (%0), %%mm0\n"
" movntq %%mm0, (%1)\n"::"r"(from),
"r"(to):"memory");
May 28, 2006
May 28, 2006
141
142
143
144
from += 8;
to += 8;
}
if (len & 7)
May 29, 2006
May 29, 2006
145
SDL_memcpy(to, from, len & 7);
Aug 22, 2003
Aug 22, 2003
146
147
148
}
#endif
May 28, 2006
May 28, 2006
149
static void
May 29, 2006
May 29, 2006
150
SDL_BlitCopy(SDL_BlitInfo * info)
Apr 26, 2001
Apr 26, 2001
151
{
May 28, 2006
May 28, 2006
152
153
154
155
156
157
158
159
160
161
Uint8 *src, *dst;
int w, h;
int srcskip, dstskip;
w = info->d_width * info->dst->BytesPerPixel;
h = info->d_height;
src = info->s_pixels;
dst = info->d_pixels;
srcskip = w + info->s_skip;
dstskip = w + info->d_skip;
Apr 11, 2004
Apr 11, 2004
162
#ifdef MMX_ASMBLIT
May 29, 2006
May 29, 2006
163
if (SDL_HasSSE()) {
May 28, 2006
May 28, 2006
164
while (h--) {
May 29, 2006
May 29, 2006
165
SDL_memcpySSE(dst, src, w);
May 28, 2006
May 28, 2006
166
167
168
src += srcskip;
dst += dstskip;
}
May 29, 2006
May 29, 2006
169
170
__asm__ __volatile__(" emms\n"::);
} else if (SDL_HasMMX()) {
May 28, 2006
May 28, 2006
171
while (h--) {
May 29, 2006
May 29, 2006
172
SDL_memcpyMMX(dst, src, w);
May 28, 2006
May 28, 2006
173
174
175
src += srcskip;
dst += dstskip;
}
May 29, 2006
May 29, 2006
176
__asm__ __volatile__(" emms\n"::);
May 28, 2006
May 28, 2006
177
} else
Aug 22, 2003
Aug 22, 2003
178
#endif
May 28, 2006
May 28, 2006
179
while (h--) {
May 29, 2006
May 29, 2006
180
SDL_memcpy(dst, src, w);
May 28, 2006
May 28, 2006
181
182
183
src += srcskip;
dst += dstskip;
}
Apr 26, 2001
Apr 26, 2001
184
185
}
May 28, 2006
May 28, 2006
186
static void
May 29, 2006
May 29, 2006
187
SDL_BlitCopyOverlap(SDL_BlitInfo * info)
Apr 26, 2001
Apr 26, 2001
188
{
May 28, 2006
May 28, 2006
189
190
191
192
193
194
195
196
197
198
199
200
Uint8 *src, *dst;
int w, h;
int srcskip, dstskip;
w = info->d_width * info->dst->BytesPerPixel;
h = info->d_height;
src = info->s_pixels;
dst = info->d_pixels;
srcskip = w + info->s_skip;
dstskip = w + info->d_skip;
if (dst < src) {
while (h--) {
May 29, 2006
May 29, 2006
201
SDL_memcpy(dst, src, w);
May 28, 2006
May 28, 2006
202
203
204
205
206
207
208
src += srcskip;
dst += dstskip;
}
} else {
src += ((h - 1) * srcskip);
dst += ((h - 1) * dstskip);
while (h--) {
May 29, 2006
May 29, 2006
209
SDL_revcpy(dst, src, w);
May 28, 2006
May 28, 2006
210
211
212
213
src -= srcskip;
dst -= dstskip;
}
}
Apr 26, 2001
Apr 26, 2001
214
215
216
}
/* Figure out which of many blit routines to set up on a surface */
May 28, 2006
May 28, 2006
217
int
May 29, 2006
May 29, 2006
218
SDL_CalculateBlit(SDL_Surface * surface)
Apr 26, 2001
Apr 26, 2001
219
{
May 28, 2006
May 28, 2006
220
221
222
223
int blit_index;
/* Clean everything out to start */
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
May 29, 2006
May 29, 2006
224
SDL_UnRLESurface(surface, 1);
May 28, 2006
May 28, 2006
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
}
surface->map->sw_blit = NULL;
/* 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
&& (surface->format->alpha != SDL_ALPHA_OPAQUE
|| surface->format->Amask)) {
blit_index |= 2;
}
/* Check for special "identity" case -- copy blit */
if (surface->map->identity && blit_index == 0) {
surface->map->sw_data->blit = SDL_BlitCopy;
/* Handle overlapping blits on the same surface */
if (surface == surface->map->dst) {
surface->map->sw_data->blit = SDL_BlitCopyOverlap;
}
} else {
if (surface->format->BitsPerPixel < 8) {
surface->map->sw_data->blit =
May 29, 2006
May 29, 2006
249
SDL_CalculateBlit0(surface, blit_index);
May 28, 2006
May 28, 2006
250
251
252
253
} else {
switch (surface->format->BytesPerPixel) {
case 1:
surface->map->sw_data->blit =
May 29, 2006
May 29, 2006
254
SDL_CalculateBlit1(surface, blit_index);
May 28, 2006
May 28, 2006
255
256
257
258
259
break;
case 2:
case 3:
case 4:
surface->map->sw_data->blit =
May 29, 2006
May 29, 2006
260
SDL_CalculateBlitN(surface, blit_index);
May 28, 2006
May 28, 2006
261
262
263
264
265
266
267
268
269
break;
default:
surface->map->sw_data->blit = NULL;
break;
}
}
}
/* Make sure we have a blit function */
if (surface->map->sw_data->blit == NULL) {
May 29, 2006
May 29, 2006
270
271
SDL_InvalidateMap(surface->map);
SDL_SetError("Blit combination not supported");
May 28, 2006
May 28, 2006
272
273
274
275
return (-1);
}
/* Choose software blitting function */
Jun 7, 2006
Jun 7, 2006
276
if (surface->flags & SDL_RLEACCELOK) {
May 28, 2006
May 28, 2006
277
278
279
if (surface->map->identity
&& (blit_index == 1
|| (blit_index == 3 && !surface->format->Amask))) {
May 29, 2006
May 29, 2006
280
if (SDL_RLESurface(surface) == 0)
May 28, 2006
May 28, 2006
281
282
surface->map->sw_blit = SDL_RLEBlit;
} else if (blit_index == 2 && surface->format->Amask) {
May 29, 2006
May 29, 2006
283
if (SDL_RLESurface(surface) == 0)
May 28, 2006
May 28, 2006
284
285
286
287
288
289
290
291
surface->map->sw_blit = SDL_RLEAlphaBlit;
}
}
if (surface->map->sw_blit == NULL) {
surface->map->sw_blit = SDL_SoftBlit;
}
return (0);
Apr 26, 2001
Apr 26, 2001
292
293
}
May 28, 2006
May 28, 2006
294
/* vi: set ts=4 sw=4 expandtab: */