Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_A.c @ 638:b0108e9dea53
Date: Sun, 11 May 2003 19:59:06 +0300
From: Pasi K?rkk?inen
Subject: [PATCH] fix SDL OpenGL segfault with DRI/Mesa drivers and Glew
Hello!
The attached patch fixes a bug in SDL which causes SDL to crash in
X11_GL_Shutdown() if you are using DRI/Mesa drivers AND glew
(http://glew.sf.net).
The bug is caused by a namespace collision affecting dlsym() to fetch wrong
pointer for glXReleaseBuffersMESA() (uninitialized pointer from glew because
the extension is NOT supported by the driver) and then SDL calling it in
X11_GL_Shutdown().
SDL should check if the glXReleaseBuffersMESA() is really supported by the
driver (from the extensions string) before calling it.
Attached patch adds extension string parsing to check if
glXReleaseBuffersMESA() is really supported (and this way
prevents the segfault).
Availability of the extensions should be _always_ checked from the
extensions string rather than using dlsym()!
Please add it to the next version of SDL.
Thanks to gltron and author of glew to help fixing this.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 28 Jun 2003 17:27:33 +0000 |
parents | f6ffac90895c |
children | 5bb080d35049 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
1
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <stdio.h> | |
29 | |
30 #include "SDL_types.h" | |
31 #include "SDL_video.h" | |
32 #include "SDL_blit.h" | |
33 | |
34 /* Functions to perform alpha blended blitting */ | |
35 | |
36 /* N->1 blending with per-surface alpha */ | |
37 static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) | |
38 { | |
39 int width = info->d_width; | |
40 int height = info->d_height; | |
41 Uint8 *src = info->s_pixels; | |
42 int srcskip = info->s_skip; | |
43 Uint8 *dst = info->d_pixels; | |
44 int dstskip = info->d_skip; | |
45 Uint8 *palmap = info->table; | |
46 SDL_PixelFormat *srcfmt = info->src; | |
47 SDL_PixelFormat *dstfmt = info->dst; | |
48 int srcbpp = srcfmt->BytesPerPixel; | |
49 | |
50 const unsigned A = srcfmt->alpha; | |
51 | |
52 while ( height-- ) { | |
53 DUFFS_LOOP4( | |
54 { | |
55 Uint32 pixel; | |
56 unsigned sR; | |
57 unsigned sG; | |
58 unsigned sB; | |
59 unsigned dR; | |
60 unsigned dG; | |
61 unsigned dB; | |
62 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
63 dR = dstfmt->palette->colors[*dst].r; | |
64 dG = dstfmt->palette->colors[*dst].g; | |
65 dB = dstfmt->palette->colors[*dst].b; | |
66 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
67 dR &= 0xff; | |
68 dG &= 0xff; | |
69 dB &= 0xff; | |
70 /* Pack RGB into 8bit pixel */ | |
71 if ( palmap == NULL ) { | |
72 *dst =((dR>>5)<<(3+2))| | |
73 ((dG>>5)<<(2))| | |
74 ((dB>>6)<<(0)); | |
75 } else { | |
76 *dst = palmap[((dR>>5)<<(3+2))| | |
77 ((dG>>5)<<(2)) | | |
78 ((dB>>6)<<(0))]; | |
79 } | |
80 dst++; | |
81 src += srcbpp; | |
82 }, | |
83 width); | |
84 src += srcskip; | |
85 dst += dstskip; | |
86 } | |
87 } | |
88 | |
89 /* N->1 blending with pixel alpha */ | |
90 static void BlitNto1PixelAlpha(SDL_BlitInfo *info) | |
91 { | |
92 int width = info->d_width; | |
93 int height = info->d_height; | |
94 Uint8 *src = info->s_pixels; | |
95 int srcskip = info->s_skip; | |
96 Uint8 *dst = info->d_pixels; | |
97 int dstskip = info->d_skip; | |
98 Uint8 *palmap = info->table; | |
99 SDL_PixelFormat *srcfmt = info->src; | |
100 SDL_PixelFormat *dstfmt = info->dst; | |
101 int srcbpp = srcfmt->BytesPerPixel; | |
102 | |
103 /* FIXME: fix alpha bit field expansion here too? */ | |
104 while ( height-- ) { | |
105 DUFFS_LOOP4( | |
106 { | |
107 Uint32 pixel; | |
108 unsigned sR; | |
109 unsigned sG; | |
110 unsigned sB; | |
111 unsigned sA; | |
112 unsigned dR; | |
113 unsigned dG; | |
114 unsigned dB; | |
115 DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA); | |
116 dR = dstfmt->palette->colors[*dst].r; | |
117 dG = dstfmt->palette->colors[*dst].g; | |
118 dB = dstfmt->palette->colors[*dst].b; | |
119 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
120 dR &= 0xff; | |
121 dG &= 0xff; | |
122 dB &= 0xff; | |
123 /* Pack RGB into 8bit pixel */ | |
124 if ( palmap == NULL ) { | |
125 *dst =((dR>>5)<<(3+2))| | |
126 ((dG>>5)<<(2))| | |
127 ((dB>>6)<<(0)); | |
128 } else { | |
129 *dst = palmap[((dR>>5)<<(3+2))| | |
130 ((dG>>5)<<(2)) | | |
131 ((dB>>6)<<(0)) ]; | |
132 } | |
133 dst++; | |
134 src += srcbpp; | |
135 }, | |
136 width); | |
137 src += srcskip; | |
138 dst += dstskip; | |
139 } | |
140 } | |
141 | |
142 /* colorkeyed N->1 blending with per-surface alpha */ | |
143 static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) | |
144 { | |
145 int width = info->d_width; | |
146 int height = info->d_height; | |
147 Uint8 *src = info->s_pixels; | |
148 int srcskip = info->s_skip; | |
149 Uint8 *dst = info->d_pixels; | |
150 int dstskip = info->d_skip; | |
151 Uint8 *palmap = info->table; | |
152 SDL_PixelFormat *srcfmt = info->src; | |
153 SDL_PixelFormat *dstfmt = info->dst; | |
154 int srcbpp = srcfmt->BytesPerPixel; | |
155 Uint32 ckey = srcfmt->colorkey; | |
156 | |
157 const int A = srcfmt->alpha; | |
158 | |
159 while ( height-- ) { | |
160 DUFFS_LOOP( | |
161 { | |
162 Uint32 pixel; | |
163 unsigned sR; | |
164 unsigned sG; | |
165 unsigned sB; | |
166 unsigned dR; | |
167 unsigned dG; | |
168 unsigned dB; | |
169 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
170 if ( pixel != ckey ) { | |
171 dR = dstfmt->palette->colors[*dst].r; | |
172 dG = dstfmt->palette->colors[*dst].g; | |
173 dB = dstfmt->palette->colors[*dst].b; | |
174 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
175 dR &= 0xff; | |
176 dG &= 0xff; | |
177 dB &= 0xff; | |
178 /* Pack RGB into 8bit pixel */ | |
179 if ( palmap == NULL ) { | |
180 *dst =((dR>>5)<<(3+2))| | |
181 ((dG>>5)<<(2)) | | |
182 ((dB>>6)<<(0)); | |
183 } else { | |
184 *dst = palmap[((dR>>5)<<(3+2))| | |
185 ((dG>>5)<<(2)) | | |
186 ((dB>>6)<<(0)) ]; | |
187 } | |
188 } | |
189 dst++; | |
190 src += srcbpp; | |
191 }, | |
192 width); | |
193 src += srcskip; | |
194 dst += dstskip; | |
195 } | |
196 } | |
197 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
198 /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
199 static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) |
0 | 200 { |
201 int width = info->d_width; | |
202 int height = info->d_height; | |
203 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
204 int srcskip = info->s_skip >> 2; | |
205 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
206 int dstskip = info->d_skip >> 2; | |
207 | |
208 while(height--) { | |
209 DUFFS_LOOP4({ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
210 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
211 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
212 *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
213 + (s & d & 0x00010101)) | 0xff000000; |
0 | 214 }, width); |
215 srcp += srcskip; | |
216 dstp += dstskip; | |
217 } | |
218 } | |
219 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
220 /* fast RGB888->(A)RGB888 blending with surface alpha */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
221 static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
222 { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
223 unsigned alpha = info->src->alpha; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
224 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
225 BlitRGBtoRGBSurfaceAlpha128(info); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
226 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
227 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
228 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
229 Uint32 *srcp = (Uint32 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
230 int srcskip = info->s_skip >> 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
231 Uint32 *dstp = (Uint32 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
232 int dstskip = info->d_skip >> 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
233 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
234 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
235 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
236 Uint32 s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
237 Uint32 d; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
238 Uint32 s1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
239 Uint32 d1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
240 s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
241 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
242 s1 = s & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
243 d1 = d & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
244 d1 = (d1 + ((s1 - d1) * alpha >> 8)) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
245 & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
246 s &= 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
247 d &= 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
248 d = (d + ((s - d) * alpha >> 8)) & 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
249 *dstp = d1 | d | 0xff000000; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
250 ++srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
251 ++dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
252 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
253 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
254 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
255 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
256 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
257 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
258 |
0 | 259 /* fast ARGB888->(A)RGB888 blending with pixel alpha */ |
260 static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) | |
261 { | |
262 int width = info->d_width; | |
263 int height = info->d_height; | |
264 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
265 int srcskip = info->s_skip >> 2; | |
266 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
267 int dstskip = info->d_skip >> 2; | |
268 | |
269 while(height--) { | |
270 DUFFS_LOOP4({ | |
271 Uint32 dalpha; | |
272 Uint32 d; | |
273 Uint32 s1; | |
274 Uint32 d1; | |
275 Uint32 s = *srcp; | |
276 Uint32 alpha = s >> 24; | |
277 /* FIXME: Here we special-case opaque alpha since the | |
278 compositioning used (>>8 instead of /255) doesn't handle | |
279 it correctly. Also special-case alpha=0 for speed? | |
280 Benchmark this! */ | |
281 if(alpha == SDL_ALPHA_OPAQUE) { | |
282 *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); | |
283 } else { | |
284 /* | |
285 * take out the middle component (green), and process | |
286 * the other two in parallel. One multiply less. | |
287 */ | |
288 d = *dstp; | |
289 dalpha = d & 0xff000000; | |
290 s1 = s & 0xff00ff; | |
291 d1 = d & 0xff00ff; | |
292 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; | |
293 s &= 0xff00; | |
294 d &= 0xff00; | |
295 d = (d + ((s - d) * alpha >> 8)) & 0xff00; | |
296 *dstp = d1 | d | dalpha; | |
297 } | |
298 ++srcp; | |
299 ++dstp; | |
300 }, width); | |
301 srcp += srcskip; | |
302 dstp += dstskip; | |
303 } | |
304 } | |
305 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
306 /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
307 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
308 /* blend a single 16 bit pixel at 50% */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
309 #define BLEND16_50(d, s, mask) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
310 ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
311 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
312 /* blend two 16 bit pixels at 50% */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
313 #define BLEND2x16_50(d, s, mask) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
314 (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
315 + (s & d & (~(mask | mask << 16)))) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
316 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
317 static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) |
0 | 318 { |
319 int width = info->d_width; | |
320 int height = info->d_height; | |
321 Uint16 *srcp = (Uint16 *)info->s_pixels; | |
322 int srcskip = info->s_skip >> 1; | |
323 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
324 int dstskip = info->d_skip >> 1; | |
325 | |
326 while(height--) { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
327 if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
328 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
329 * Source and destination not aligned, pipeline it. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
330 * This is mostly a win for big blits but no loss for |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
331 * small ones |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
332 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
333 Uint32 prev_sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
334 int w = width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
335 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
336 /* handle odd destination */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
337 if((unsigned long)dstp & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
338 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
339 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
340 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
341 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
342 w--; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
343 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
344 srcp++; /* srcp is now 32-bit aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
345 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
346 /* bootstrap pipeline with first halfword */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
347 prev_sw = ((Uint32 *)srcp)[-1]; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
348 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
349 while(w > 1) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
350 Uint32 sw, dw, s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
351 sw = *(Uint32 *)srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
352 dw = *(Uint32 *)dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
353 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
354 s = (prev_sw << 16) + (sw >> 16); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
355 else |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
356 s = (prev_sw >> 16) + (sw << 16); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
357 prev_sw = sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
358 *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
359 dstp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
360 srcp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
361 w -= 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
362 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
363 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
364 /* final pixel if any */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
365 if(w) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
366 Uint16 d = *dstp, s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
367 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
368 s = prev_sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
369 else |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
370 s = prev_sw >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
371 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
372 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
373 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
374 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
375 srcp += srcskip - 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
376 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
377 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
378 /* source and destination are aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
379 int w = width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
380 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
381 /* first odd pixel? */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
382 if((unsigned long)srcp & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
383 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
384 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
385 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
386 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
387 w--; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
388 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
389 /* srcp and dstp are now 32-bit aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
390 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
391 while(w > 1) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
392 Uint32 sw = *(Uint32 *)srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
393 Uint32 dw = *(Uint32 *)dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
394 *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
395 srcp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
396 dstp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
397 w -= 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
398 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
399 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
400 /* last odd pixel? */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
401 if(w) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
402 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
403 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
404 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
405 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
406 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
407 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
408 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
409 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
410 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
411 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
412 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
413 /* fast RGB565->RGB565 blending with surface alpha */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
414 static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
415 { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
416 unsigned alpha = info->src->alpha; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
417 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
418 Blit16to16SurfaceAlpha128(info, 0xf7de); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
419 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
420 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
421 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
422 Uint16 *srcp = (Uint16 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
423 int srcskip = info->s_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
424 Uint16 *dstp = (Uint16 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
425 int dstskip = info->d_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
426 alpha >>= 3; /* downscale alpha to 5 bits */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
427 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
428 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
429 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
430 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
431 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
432 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
433 * shift out the middle component (green) to |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
434 * the high 16 bits, and process all three RGB |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
435 * components at the same time. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
436 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
437 s = (s | s << 16) & 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
438 d = (d | d << 16) & 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
439 d += (s - d) * alpha >> 5; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
440 d &= 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
441 *dstp++ = d | d >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
442 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
443 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
444 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
445 } |
0 | 446 } |
447 } | |
448 | |
449 /* fast RGB555->RGB555 blending with surface alpha */ | |
450 static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) | |
451 { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
452 unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
453 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
454 Blit16to16SurfaceAlpha128(info, 0xfbde); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
455 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
456 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
457 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
458 Uint16 *srcp = (Uint16 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
459 int srcskip = info->s_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
460 Uint16 *dstp = (Uint16 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
461 int dstskip = info->d_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
462 alpha >>= 3; /* downscale alpha to 5 bits */ |
0 | 463 |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
464 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
465 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
466 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
467 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
468 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
469 * shift out the middle component (green) to |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
470 * the high 16 bits, and process all three RGB |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
471 * components at the same time. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
472 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
473 s = (s | s << 16) & 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
474 d = (d | d << 16) & 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
475 d += (s - d) * alpha >> 5; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
476 d &= 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
477 *dstp++ = d | d >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
478 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
479 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
480 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
481 } |
0 | 482 } |
483 } | |
484 | |
485 /* fast ARGB8888->RGB565 blending with pixel alpha */ | |
486 static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) | |
487 { | |
488 int width = info->d_width; | |
489 int height = info->d_height; | |
490 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
491 int srcskip = info->s_skip >> 2; | |
492 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
493 int dstskip = info->d_skip >> 1; | |
494 | |
495 while(height--) { | |
496 DUFFS_LOOP4({ | |
497 Uint32 s = *srcp; | |
498 unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ | |
499 /* FIXME: Here we special-case opaque alpha since the | |
500 compositioning used (>>8 instead of /255) doesn't handle | |
501 it correctly. Also special-case alpha=0 for speed? | |
502 Benchmark this! */ | |
503 if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { | |
504 *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0) | |
505 + (s >> 3 & 0x1f); | |
506 } else { | |
507 Uint32 d = *dstp; | |
508 /* | |
509 * convert source and destination to G0RAB65565 | |
510 * and blend all components at the same time | |
511 */ | |
512 s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) | |
513 + (s >> 3 & 0x1f); | |
514 d = (d | d << 16) & 0x07e0f81f; | |
515 d += (s - d) * alpha >> 5; | |
516 d &= 0x07e0f81f; | |
517 *dstp = d | d >> 16; | |
518 } | |
519 srcp++; | |
520 dstp++; | |
521 }, width); | |
522 srcp += srcskip; | |
523 dstp += dstskip; | |
524 } | |
525 } | |
526 | |
527 /* fast ARGB8888->RGB555 blending with pixel alpha */ | |
528 static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) | |
529 { | |
530 int width = info->d_width; | |
531 int height = info->d_height; | |
532 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
533 int srcskip = info->s_skip >> 2; | |
534 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
535 int dstskip = info->d_skip >> 1; | |
536 | |
537 while(height--) { | |
538 DUFFS_LOOP4({ | |
539 unsigned alpha; | |
540 Uint32 s = *srcp; | |
541 alpha = s >> 27; /* downscale alpha to 5 bits */ | |
542 /* FIXME: Here we special-case opaque alpha since the | |
543 compositioning used (>>8 instead of /255) doesn't handle | |
544 it correctly. Also special-case alpha=0 for speed? | |
545 Benchmark this! */ | |
546 if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { | |
547 *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) | |
548 + (s >> 3 & 0x1f); | |
549 } else { | |
550 Uint32 d = *dstp; | |
551 /* | |
552 * convert source and destination to G0RAB65565 | |
553 * and blend all components at the same time | |
554 */ | |
555 s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) | |
556 + (s >> 3 & 0x1f); | |
557 d = (d | d << 16) & 0x03e07c1f; | |
558 d += (s - d) * alpha >> 5; | |
559 d &= 0x03e07c1f; | |
560 *dstp = d | d >> 16; | |
561 } | |
562 srcp++; | |
563 dstp++; | |
564 }, width); | |
565 srcp += srcskip; | |
566 dstp += dstskip; | |
567 } | |
568 } | |
569 | |
570 /* General (slow) N->N blending with per-surface alpha */ | |
571 static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) | |
572 { | |
573 int width = info->d_width; | |
574 int height = info->d_height; | |
575 Uint8 *src = info->s_pixels; | |
576 int srcskip = info->s_skip; | |
577 Uint8 *dst = info->d_pixels; | |
578 int dstskip = info->d_skip; | |
579 SDL_PixelFormat *srcfmt = info->src; | |
580 SDL_PixelFormat *dstfmt = info->dst; | |
581 int srcbpp = srcfmt->BytesPerPixel; | |
582 int dstbpp = dstfmt->BytesPerPixel; | |
583 unsigned sA = srcfmt->alpha; | |
584 unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; | |
585 | |
586 while ( height-- ) { | |
587 DUFFS_LOOP4( | |
588 { | |
589 Uint32 pixel; | |
590 unsigned sR; | |
591 unsigned sG; | |
592 unsigned sB; | |
593 unsigned dR; | |
594 unsigned dG; | |
595 unsigned dB; | |
596 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
597 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); | |
598 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
599 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
600 src += srcbpp; | |
601 dst += dstbpp; | |
602 }, | |
603 width); | |
604 src += srcskip; | |
605 dst += dstskip; | |
606 } | |
607 } | |
608 | |
609 /* General (slow) colorkeyed N->N blending with per-surface alpha */ | |
610 static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) | |
611 { | |
612 int width = info->d_width; | |
613 int height = info->d_height; | |
614 Uint8 *src = info->s_pixels; | |
615 int srcskip = info->s_skip; | |
616 Uint8 *dst = info->d_pixels; | |
617 int dstskip = info->d_skip; | |
618 SDL_PixelFormat *srcfmt = info->src; | |
619 SDL_PixelFormat *dstfmt = info->dst; | |
620 Uint32 ckey = srcfmt->colorkey; | |
621 int srcbpp = srcfmt->BytesPerPixel; | |
622 int dstbpp = dstfmt->BytesPerPixel; | |
623 unsigned sA = srcfmt->alpha; | |
624 unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; | |
625 | |
626 while ( height-- ) { | |
627 DUFFS_LOOP4( | |
628 { | |
629 Uint32 pixel; | |
630 unsigned sR; | |
631 unsigned sG; | |
632 unsigned sB; | |
633 unsigned dR; | |
634 unsigned dG; | |
635 unsigned dB; | |
636 RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); | |
637 if(pixel != ckey) { | |
638 RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); | |
639 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); | |
640 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
641 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
642 } | |
643 src += srcbpp; | |
644 dst += dstbpp; | |
645 }, | |
646 width); | |
647 src += srcskip; | |
648 dst += dstskip; | |
649 } | |
650 } | |
651 | |
652 /* General (slow) N->N blending with pixel alpha */ | |
653 static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) | |
654 { | |
655 int width = info->d_width; | |
656 int height = info->d_height; | |
657 Uint8 *src = info->s_pixels; | |
658 int srcskip = info->s_skip; | |
659 Uint8 *dst = info->d_pixels; | |
660 int dstskip = info->d_skip; | |
661 SDL_PixelFormat *srcfmt = info->src; | |
662 SDL_PixelFormat *dstfmt = info->dst; | |
663 | |
664 int srcbpp; | |
665 int dstbpp; | |
666 | |
667 /* Set up some basic variables */ | |
668 srcbpp = srcfmt->BytesPerPixel; | |
669 dstbpp = dstfmt->BytesPerPixel; | |
670 | |
671 /* FIXME: for 8bpp source alpha, this doesn't get opaque values | |
672 quite right. for <8bpp source alpha, it gets them very wrong | |
673 (check all macros!) | |
674 It is unclear whether there is a good general solution that doesn't | |
675 need a branch (or a divide). */ | |
676 while ( height-- ) { | |
677 DUFFS_LOOP4( | |
678 { | |
679 Uint32 pixel; | |
680 unsigned sR; | |
681 unsigned sG; | |
682 unsigned sB; | |
683 unsigned dR; | |
684 unsigned dG; | |
685 unsigned dB; | |
686 unsigned sA; | |
687 unsigned dA; | |
688 DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA); | |
689 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); | |
690 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
691 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
692 src += srcbpp; | |
693 dst += dstbpp; | |
694 }, | |
695 width); | |
696 src += srcskip; | |
697 dst += dstskip; | |
698 } | |
699 } | |
700 | |
701 | |
702 SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index) | |
703 { | |
704 SDL_PixelFormat *sf = surface->format; | |
705 SDL_PixelFormat *df = surface->map->dst->format; | |
706 | |
707 if(sf->Amask == 0) { | |
708 if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { | |
709 if(df->BytesPerPixel == 1) | |
710 return BlitNto1SurfaceAlphaKey; | |
711 else | |
712 return BlitNtoNSurfaceAlphaKey; | |
713 } else { | |
714 /* Per-surface alpha blits */ | |
715 switch(df->BytesPerPixel) { | |
716 case 1: | |
717 return BlitNto1SurfaceAlpha; | |
718 | |
719 case 2: | |
720 if(surface->map->identity) { | |
721 if(df->Gmask == 0x7e0) | |
722 return Blit565to565SurfaceAlpha; | |
723 else if(df->Gmask == 0x3e0) | |
724 return Blit555to555SurfaceAlpha; | |
725 } | |
726 return BlitNtoNSurfaceAlpha; | |
727 | |
728 case 4: | |
729 if(sf->Rmask == df->Rmask | |
730 && sf->Gmask == df->Gmask | |
731 && sf->Bmask == df->Bmask | |
732 && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff | |
733 && sf->BytesPerPixel == 4) | |
734 return BlitRGBtoRGBSurfaceAlpha; | |
735 else | |
736 return BlitNtoNSurfaceAlpha; | |
737 | |
738 case 3: | |
739 default: | |
740 return BlitNtoNSurfaceAlpha; | |
741 } | |
742 } | |
743 } else { | |
744 /* Per-pixel alpha blits */ | |
745 switch(df->BytesPerPixel) { | |
746 case 1: | |
747 return BlitNto1PixelAlpha; | |
748 | |
749 case 2: | |
750 if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 | |
751 && sf->Gmask == 0xff00 | |
752 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) | |
753 || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { | |
754 if(df->Gmask == 0x7e0) | |
755 return BlitARGBto565PixelAlpha; | |
756 else if(df->Gmask == 0x3e0) | |
757 return BlitARGBto555PixelAlpha; | |
758 } | |
759 return BlitNtoNPixelAlpha; | |
760 | |
761 case 4: | |
762 if(sf->Amask == 0xff000000 | |
763 && sf->Rmask == df->Rmask | |
764 && sf->Gmask == df->Gmask | |
765 && sf->Bmask == df->Bmask | |
766 && sf->BytesPerPixel == 4) | |
767 return BlitRGBtoRGBPixelAlpha; | |
768 return BlitNtoNPixelAlpha; | |
769 | |
770 case 3: | |
771 default: | |
772 return BlitNtoNPixelAlpha; | |
773 } | |
774 } | |
775 } | |
776 |