Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit.c @ 821:30168104389f
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL
1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).
And I've added to testvidinfo test color-keyed blits benchmark (maybe need to add alpha blits benchmark too ?). Currently Photon not supporting any alpha hardware blittings (all drivers lack of alpha blitting code support, only software alpha blitting exist in photon, which is hundreds times slowest than the SDL's one). So I've not added the alpha support. I suppose new QNX 6.3 will have the hardware alpha support, so when it will be done, I'll add alpha support.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 14 Feb 2004 20:22:21 +0000 |
parents | b8d311d90021 |
children | 9ef41050100c |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
769
b8d311d90021
Updated copyright information for 2004 (Happy New Year!)
Sam Lantinga <slouken@libsdl.org>
parents:
739
diff
changeset
|
3 Copyright (C) 1997-2004 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:
0
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 #include <stdlib.h> | |
30 #include <string.h> | |
31 | |
32 #include "SDL_error.h" | |
33 #include "SDL_video.h" | |
34 #include "SDL_sysvideo.h" | |
35 #include "SDL_blit.h" | |
36 #include "SDL_RLEaccel_c.h" | |
37 #include "SDL_pixels_c.h" | |
38 #include "SDL_memops.h" | |
39 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
40 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
697
diff
changeset
|
41 #include "SDL_cpuinfo.h" |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
42 #include "mmx.h" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
43 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
44 |
0 | 45 /* The general purpose software blit routine */ |
46 static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
47 SDL_Surface *dst, SDL_Rect *dstrect) | |
48 { | |
49 int okay; | |
50 int src_locked; | |
51 int dst_locked; | |
52 | |
53 /* Everything is okay at the beginning... */ | |
54 okay = 1; | |
55 | |
56 /* Lock the destination if it's in hardware */ | |
57 dst_locked = 0; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
58 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
59 if ( SDL_LockSurface(dst) < 0 ) { |
0 | 60 okay = 0; |
61 } else { | |
62 dst_locked = 1; | |
63 } | |
64 } | |
65 /* Lock the source if it's in hardware */ | |
66 src_locked = 0; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
67 if ( SDL_MUSTLOCK(src) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
68 if ( SDL_LockSurface(src) < 0 ) { |
0 | 69 okay = 0; |
70 } else { | |
71 src_locked = 1; | |
72 } | |
73 } | |
74 | |
75 /* Set up source and destination buffer pointers, and BLIT! */ | |
76 if ( okay && srcrect->w && srcrect->h ) { | |
77 SDL_BlitInfo info; | |
78 SDL_loblit RunBlit; | |
79 | |
80 /* Set up the blit information */ | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
81 info.s_pixels = (Uint8 *)src->pixels + |
0 | 82 (Uint16)srcrect->y*src->pitch + |
83 (Uint16)srcrect->x*src->format->BytesPerPixel; | |
84 info.s_width = srcrect->w; | |
85 info.s_height = srcrect->h; | |
86 info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
87 info.d_pixels = (Uint8 *)dst->pixels + |
0 | 88 (Uint16)dstrect->y*dst->pitch + |
89 (Uint16)dstrect->x*dst->format->BytesPerPixel; | |
90 info.d_width = dstrect->w; | |
91 info.d_height = dstrect->h; | |
92 info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel; | |
93 info.aux_data = src->map->sw_data->aux_data; | |
94 info.src = src->format; | |
95 info.table = src->map->table; | |
96 info.dst = dst->format; | |
97 RunBlit = src->map->sw_data->blit; | |
98 | |
99 /* Run the actual software blit */ | |
100 RunBlit(&info); | |
101 } | |
102 | |
103 /* We need to unlock the surfaces if they're locked */ | |
104 if ( dst_locked ) { | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
105 SDL_UnlockSurface(dst); |
310
c97c1d3b3b5c
Blit bug fix from John Popplewell
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
106 } |
0 | 107 if ( src_locked ) { |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
108 SDL_UnlockSurface(src); |
0 | 109 } |
110 /* Blit is done! */ | |
111 return(okay ? 0 : -1); | |
112 } | |
113 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
114 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
115 void SDL_memcpyMMX(char* to,char* from,int len) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
116 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
117 int i; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
118 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
119 for(i=0; i<len/8; i++) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
120 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
121 " movq (%0), %%mm0\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
122 " movq %%mm0, (%1)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
123 : : "r" (from), "r" (to) : "memory"); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
124 from+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
125 to+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
126 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
127 if (len&7) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
128 SDL_memcpy(to, from, len&7); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
129 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
130 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
131 void SDL_memcpySSE(char* to,char* from,int len) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
132 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
133 int i; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
134 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
135 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
136 " prefetchnta (%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
137 " prefetchnta 64(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
138 " prefetchnta 128(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
139 " prefetchnta 192(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
140 : : "r" (from) ); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
141 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
142 for(i=0; i<len/8; i++) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
143 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
144 " prefetchnta 256(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
145 " movq (%0), %%mm0\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
146 " movntq %%mm0, (%1)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
147 : : "r" (from), "r" (to) : "memory"); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
148 from+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
149 to+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
150 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
151 if (len&7) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
152 SDL_memcpy(to, from, len&7); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
153 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
154 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
155 |
0 | 156 static void SDL_BlitCopy(SDL_BlitInfo *info) |
157 { | |
158 Uint8 *src, *dst; | |
159 int w, h; | |
160 int srcskip, dstskip; | |
161 | |
162 w = info->d_width*info->dst->BytesPerPixel; | |
163 h = info->d_height; | |
164 src = info->s_pixels; | |
165 dst = info->d_pixels; | |
166 srcskip = w+info->s_skip; | |
167 dstskip = w+info->d_skip; | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
168 #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
697
diff
changeset
|
169 if(SDL_HasSSE()) |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
170 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
171 while ( h-- ) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
172 SDL_memcpySSE(dst, src, w); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
173 src += srcskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
174 dst += dstskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
175 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
176 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
177 " emms\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
178 ::); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
179 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
180 else |
739
22dbf364c017
Added SDL_HasMMX(), SDL_Has3DNow(), SDL_HasSSE() in SDL_cpuinfo.h
Sam Lantinga <slouken@libsdl.org>
parents:
697
diff
changeset
|
181 if(SDL_HasMMX()) |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
182 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
183 while ( h-- ) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
184 SDL_memcpyMMX(dst, src, w); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
185 src += srcskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
186 dst += dstskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
187 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
188 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
189 " emms\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
190 ::); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
191 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
192 else |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
193 #endif |
0 | 194 while ( h-- ) { |
195 SDL_memcpy(dst, src, w); | |
196 src += srcskip; | |
197 dst += dstskip; | |
198 } | |
199 } | |
200 | |
201 static void SDL_BlitCopyOverlap(SDL_BlitInfo *info) | |
202 { | |
203 Uint8 *src, *dst; | |
204 int w, h; | |
205 int srcskip, dstskip; | |
206 | |
207 w = info->d_width*info->dst->BytesPerPixel; | |
208 h = info->d_height; | |
209 src = info->s_pixels; | |
210 dst = info->d_pixels; | |
211 srcskip = w+info->s_skip; | |
212 dstskip = w+info->d_skip; | |
213 if ( dst < src ) { | |
214 while ( h-- ) { | |
215 SDL_memcpy(dst, src, w); | |
216 src += srcskip; | |
217 dst += dstskip; | |
218 } | |
219 } else { | |
220 src += ((h-1) * srcskip); | |
221 dst += ((h-1) * dstskip); | |
222 while ( h-- ) { | |
223 SDL_revcpy(dst, src, w); | |
224 src -= srcskip; | |
225 dst -= dstskip; | |
226 } | |
227 } | |
228 } | |
229 | |
230 /* Figure out which of many blit routines to set up on a surface */ | |
231 int SDL_CalculateBlit(SDL_Surface *surface) | |
232 { | |
233 int blit_index; | |
234 | |
235 /* Clean everything out to start */ | |
236 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
237 SDL_UnRLESurface(surface, 1); | |
238 } | |
239 surface->map->sw_blit = NULL; | |
240 | |
241 /* Figure out if an accelerated hardware blit is possible */ | |
242 surface->flags &= ~SDL_HWACCEL; | |
243 if ( surface->map->identity ) { | |
244 int hw_blit_ok; | |
245 | |
246 if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { | |
247 /* We only support accelerated blitting to hardware */ | |
248 if ( surface->map->dst->flags & SDL_HWSURFACE ) { | |
249 hw_blit_ok = current_video->info.blit_hw; | |
250 } else { | |
251 hw_blit_ok = 0; | |
252 } | |
253 if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { | |
254 hw_blit_ok = current_video->info.blit_hw_CC; | |
255 } | |
256 if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { | |
257 hw_blit_ok = current_video->info.blit_hw_A; | |
258 } | |
259 } else { | |
260 /* We only support accelerated blitting to hardware */ | |
261 if ( surface->map->dst->flags & SDL_HWSURFACE ) { | |
262 hw_blit_ok = current_video->info.blit_sw; | |
263 } else { | |
264 hw_blit_ok = 0; | |
265 } | |
266 if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { | |
267 hw_blit_ok = current_video->info.blit_sw_CC; | |
268 } | |
269 if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { | |
270 hw_blit_ok = current_video->info.blit_sw_A; | |
271 } | |
272 } | |
273 if ( hw_blit_ok ) { | |
274 SDL_VideoDevice *video = current_video; | |
275 SDL_VideoDevice *this = current_video; | |
276 video->CheckHWBlit(this, surface, surface->map->dst); | |
277 } | |
278 } | |
279 | |
280 /* Get the blit function index, based on surface mode */ | |
281 /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ | |
282 blit_index = 0; | |
283 blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; | |
284 if ( surface->flags & SDL_SRCALPHA | |
285 && (surface->format->alpha != SDL_ALPHA_OPAQUE | |
286 || surface->format->Amask) ) { | |
287 blit_index |= 2; | |
288 } | |
289 | |
290 /* Check for special "identity" case -- copy blit */ | |
291 if ( surface->map->identity && blit_index == 0 ) { | |
292 surface->map->sw_data->blit = SDL_BlitCopy; | |
293 | |
294 /* Handle overlapping blits on the same surface */ | |
295 if ( surface == surface->map->dst ) { | |
296 surface->map->sw_data->blit = SDL_BlitCopyOverlap; | |
297 } | |
298 } else { | |
299 if ( surface->format->BitsPerPixel < 8 ) { | |
300 surface->map->sw_data->blit = | |
301 SDL_CalculateBlit0(surface, blit_index); | |
302 } else { | |
303 switch ( surface->format->BytesPerPixel ) { | |
304 case 1: | |
305 surface->map->sw_data->blit = | |
306 SDL_CalculateBlit1(surface, blit_index); | |
307 break; | |
308 case 2: | |
309 case 3: | |
310 case 4: | |
311 surface->map->sw_data->blit = | |
312 SDL_CalculateBlitN(surface, blit_index); | |
313 break; | |
314 default: | |
315 surface->map->sw_data->blit = NULL; | |
316 break; | |
317 } | |
318 } | |
319 } | |
320 /* Make sure we have a blit function */ | |
321 if ( surface->map->sw_data->blit == NULL ) { | |
322 SDL_InvalidateMap(surface->map); | |
323 SDL_SetError("Blit combination not supported"); | |
324 return(-1); | |
325 } | |
326 | |
327 /* Choose software blitting function */ | |
328 if(surface->flags & SDL_RLEACCELOK | |
329 && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { | |
330 | |
331 if(surface->map->identity | |
332 && (blit_index == 1 | |
333 || (blit_index == 3 && !surface->format->Amask))) { | |
334 if ( SDL_RLESurface(surface) == 0 ) | |
335 surface->map->sw_blit = SDL_RLEBlit; | |
336 } else if(blit_index == 2 && surface->format->Amask) { | |
337 if ( SDL_RLESurface(surface) == 0 ) | |
338 surface->map->sw_blit = SDL_RLEAlphaBlit; | |
339 } | |
340 } | |
341 | |
342 if ( surface->map->sw_blit == NULL ) { | |
343 surface->map->sw_blit = SDL_SoftBlit; | |
344 } | |
345 return(0); | |
346 } | |
347 |