Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit.c @ 689:5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
From: Stephane Marchesin
Subject: Re: [SDL] [patch] MMX alpha blit patches with MMX detection
I think everything is correct now. I've done as much testing as I could,
but some real-world testing wouldn't hurt, I think.
The patch is here : http://icps.u-strasbg.fr/~marchesin/sdl_mmxblit.patch
If you do byte-by-byte comparison of the output between C and MMX
functions, you'll notice that the results for 555 and 565 RGB alpha
blits aren't exactly the same. This is because MMX functions for 555 and
565 RGB have an higher accuracy. If you want the exact same behaviour
that's possible by masking the three lower alpha bits in the MMX
functions. Just ask !
I removed one MMX function because after I fixed it to match its C
equivalent, it revealed to be slower than the C version on a PIII
(although a bit faster on an Athlon XP).
I've also added MMX and PIII replacements for SDL_memcpy. Those provide
some speed up in testvidinfo -benchmark (at least for me, under linux &
X11).
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 22 Aug 2003 05:51:19 +0000 |
parents | 4314a501d7be |
children | 8468fc0504f3 |
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:
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) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
41 #include "mmx.h" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
42 /* Function to check the CPU flags */ |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
43 #define MMX_CPU 0x800000 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
44 #define SSE_CPU 0x2000000 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
45 #define CPU_Flags() Hermes_X86_CPU() |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
46 #define X86_ASSEMBLER |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
47 #define HermesConverterInterface void |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
48 #define HermesClearInterface void |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
49 #define STACKCALL |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
50 #include "HeadX86.h" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
51 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
52 |
0 | 53 /* The general purpose software blit routine */ |
54 static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, | |
55 SDL_Surface *dst, SDL_Rect *dstrect) | |
56 { | |
57 int okay; | |
58 int src_locked; | |
59 int dst_locked; | |
60 | |
61 /* Everything is okay at the beginning... */ | |
62 okay = 1; | |
63 | |
64 /* Lock the destination if it's in hardware */ | |
65 dst_locked = 0; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
66 if ( SDL_MUSTLOCK(dst) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
67 if ( SDL_LockSurface(dst) < 0 ) { |
0 | 68 okay = 0; |
69 } else { | |
70 dst_locked = 1; | |
71 } | |
72 } | |
73 /* Lock the source if it's in hardware */ | |
74 src_locked = 0; | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
75 if ( SDL_MUSTLOCK(src) ) { |
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
76 if ( SDL_LockSurface(src) < 0 ) { |
0 | 77 okay = 0; |
78 } else { | |
79 src_locked = 1; | |
80 } | |
81 } | |
82 | |
83 /* Set up source and destination buffer pointers, and BLIT! */ | |
84 if ( okay && srcrect->w && srcrect->h ) { | |
85 SDL_BlitInfo info; | |
86 SDL_loblit RunBlit; | |
87 | |
88 /* 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
|
89 info.s_pixels = (Uint8 *)src->pixels + |
0 | 90 (Uint16)srcrect->y*src->pitch + |
91 (Uint16)srcrect->x*src->format->BytesPerPixel; | |
92 info.s_width = srcrect->w; | |
93 info.s_height = srcrect->h; | |
94 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
|
95 info.d_pixels = (Uint8 *)dst->pixels + |
0 | 96 (Uint16)dstrect->y*dst->pitch + |
97 (Uint16)dstrect->x*dst->format->BytesPerPixel; | |
98 info.d_width = dstrect->w; | |
99 info.d_height = dstrect->h; | |
100 info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel; | |
101 info.aux_data = src->map->sw_data->aux_data; | |
102 info.src = src->format; | |
103 info.table = src->map->table; | |
104 info.dst = dst->format; | |
105 RunBlit = src->map->sw_data->blit; | |
106 | |
107 /* Run the actual software blit */ | |
108 RunBlit(&info); | |
109 } | |
110 | |
111 /* We need to unlock the surfaces if they're locked */ | |
112 if ( dst_locked ) { | |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
113 SDL_UnlockSurface(dst); |
310
c97c1d3b3b5c
Blit bug fix from John Popplewell
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
114 } |
0 | 115 if ( src_locked ) { |
526
4314a501d7be
Fixed a crash blitting RLE surfaces to RLE surfaces
Sam Lantinga <slouken@libsdl.org>
parents:
310
diff
changeset
|
116 SDL_UnlockSurface(src); |
0 | 117 } |
118 /* Blit is done! */ | |
119 return(okay ? 0 : -1); | |
120 } | |
121 | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
122 #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
|
123 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
|
124 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
125 int i; |
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 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
|
128 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
129 " movq (%0), %%mm0\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
130 " movq %%mm0, (%1)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
131 : : "r" (from), "r" (to) : "memory"); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
132 from+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
133 to+=8; |
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 if (len&7) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
136 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
|
137 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
138 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
139 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
|
140 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
141 int i; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
142 |
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 (%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
145 " prefetchnta 64(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
146 " prefetchnta 128(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
147 " prefetchnta 192(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
148 : : "r" (from) ); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
149 |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
150 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
|
151 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
152 " prefetchnta 256(%0)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
153 " movq (%0), %%mm0\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
154 " movntq %%mm0, (%1)\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
155 : : "r" (from), "r" (to) : "memory"); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
156 from+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
157 to+=8; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
158 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
159 if (len&7) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
160 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
|
161 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
162 #endif |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
163 |
0 | 164 static void SDL_BlitCopy(SDL_BlitInfo *info) |
165 { | |
166 Uint8 *src, *dst; | |
167 int w, h; | |
168 int srcskip, dstskip; | |
689
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
169 Uint32 f; |
0 | 170 |
171 w = info->d_width*info->dst->BytesPerPixel; | |
172 h = info->d_height; | |
173 src = info->s_pixels; | |
174 dst = info->d_pixels; | |
175 srcskip = w+info->s_skip; | |
176 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
|
177 #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
|
178 f=CPU_Flags(); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
179 if((f&(MMX_CPU|SSE_CPU))==(MMX_CPU|SSE_CPU)) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
180 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
181 while ( h-- ) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
182 SDL_memcpySSE(dst, src, w); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
183 src += srcskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
184 dst += dstskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
185 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
186 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
187 " emms\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
188 ::); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
189 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
190 else |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
191 if((f&(MMX_CPU))!=0) |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
192 { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
193 while ( h-- ) { |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
194 SDL_memcpyMMX(dst, src, w); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
195 src += srcskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
196 dst += dstskip; |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
197 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
198 __asm__ __volatile__ ( |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
199 " emms\n" |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
200 ::); |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
201 } |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
202 else |
5bb080d35049
Date: Tue, 19 Aug 2003 17:57:00 +0200
Sam Lantinga <slouken@libsdl.org>
parents:
526
diff
changeset
|
203 #endif |
0 | 204 while ( h-- ) { |
205 SDL_memcpy(dst, src, w); | |
206 src += srcskip; | |
207 dst += dstskip; | |
208 } | |
209 } | |
210 | |
211 static void SDL_BlitCopyOverlap(SDL_BlitInfo *info) | |
212 { | |
213 Uint8 *src, *dst; | |
214 int w, h; | |
215 int srcskip, dstskip; | |
216 | |
217 w = info->d_width*info->dst->BytesPerPixel; | |
218 h = info->d_height; | |
219 src = info->s_pixels; | |
220 dst = info->d_pixels; | |
221 srcskip = w+info->s_skip; | |
222 dstskip = w+info->d_skip; | |
223 if ( dst < src ) { | |
224 while ( h-- ) { | |
225 SDL_memcpy(dst, src, w); | |
226 src += srcskip; | |
227 dst += dstskip; | |
228 } | |
229 } else { | |
230 src += ((h-1) * srcskip); | |
231 dst += ((h-1) * dstskip); | |
232 while ( h-- ) { | |
233 SDL_revcpy(dst, src, w); | |
234 src -= srcskip; | |
235 dst -= dstskip; | |
236 } | |
237 } | |
238 } | |
239 | |
240 /* Figure out which of many blit routines to set up on a surface */ | |
241 int SDL_CalculateBlit(SDL_Surface *surface) | |
242 { | |
243 int blit_index; | |
244 | |
245 /* Clean everything out to start */ | |
246 if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { | |
247 SDL_UnRLESurface(surface, 1); | |
248 } | |
249 surface->map->sw_blit = NULL; | |
250 | |
251 /* Figure out if an accelerated hardware blit is possible */ | |
252 surface->flags &= ~SDL_HWACCEL; | |
253 if ( surface->map->identity ) { | |
254 int hw_blit_ok; | |
255 | |
256 if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { | |
257 /* We only support accelerated blitting to hardware */ | |
258 if ( surface->map->dst->flags & SDL_HWSURFACE ) { | |
259 hw_blit_ok = current_video->info.blit_hw; | |
260 } else { | |
261 hw_blit_ok = 0; | |
262 } | |
263 if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { | |
264 hw_blit_ok = current_video->info.blit_hw_CC; | |
265 } | |
266 if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { | |
267 hw_blit_ok = current_video->info.blit_hw_A; | |
268 } | |
269 } else { | |
270 /* We only support accelerated blitting to hardware */ | |
271 if ( surface->map->dst->flags & SDL_HWSURFACE ) { | |
272 hw_blit_ok = current_video->info.blit_sw; | |
273 } else { | |
274 hw_blit_ok = 0; | |
275 } | |
276 if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { | |
277 hw_blit_ok = current_video->info.blit_sw_CC; | |
278 } | |
279 if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { | |
280 hw_blit_ok = current_video->info.blit_sw_A; | |
281 } | |
282 } | |
283 if ( hw_blit_ok ) { | |
284 SDL_VideoDevice *video = current_video; | |
285 SDL_VideoDevice *this = current_video; | |
286 video->CheckHWBlit(this, surface, surface->map->dst); | |
287 } | |
288 } | |
289 | |
290 /* Get the blit function index, based on surface mode */ | |
291 /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ | |
292 blit_index = 0; | |
293 blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; | |
294 if ( surface->flags & SDL_SRCALPHA | |
295 && (surface->format->alpha != SDL_ALPHA_OPAQUE | |
296 || surface->format->Amask) ) { | |
297 blit_index |= 2; | |
298 } | |
299 | |
300 /* Check for special "identity" case -- copy blit */ | |
301 if ( surface->map->identity && blit_index == 0 ) { | |
302 surface->map->sw_data->blit = SDL_BlitCopy; | |
303 | |
304 /* Handle overlapping blits on the same surface */ | |
305 if ( surface == surface->map->dst ) { | |
306 surface->map->sw_data->blit = SDL_BlitCopyOverlap; | |
307 } | |
308 } else { | |
309 if ( surface->format->BitsPerPixel < 8 ) { | |
310 surface->map->sw_data->blit = | |
311 SDL_CalculateBlit0(surface, blit_index); | |
312 } else { | |
313 switch ( surface->format->BytesPerPixel ) { | |
314 case 1: | |
315 surface->map->sw_data->blit = | |
316 SDL_CalculateBlit1(surface, blit_index); | |
317 break; | |
318 case 2: | |
319 case 3: | |
320 case 4: | |
321 surface->map->sw_data->blit = | |
322 SDL_CalculateBlitN(surface, blit_index); | |
323 break; | |
324 default: | |
325 surface->map->sw_data->blit = NULL; | |
326 break; | |
327 } | |
328 } | |
329 } | |
330 /* Make sure we have a blit function */ | |
331 if ( surface->map->sw_data->blit == NULL ) { | |
332 SDL_InvalidateMap(surface->map); | |
333 SDL_SetError("Blit combination not supported"); | |
334 return(-1); | |
335 } | |
336 | |
337 /* Choose software blitting function */ | |
338 if(surface->flags & SDL_RLEACCELOK | |
339 && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { | |
340 | |
341 if(surface->map->identity | |
342 && (blit_index == 1 | |
343 || (blit_index == 3 && !surface->format->Amask))) { | |
344 if ( SDL_RLESurface(surface) == 0 ) | |
345 surface->map->sw_blit = SDL_RLEBlit; | |
346 } else if(blit_index == 2 && surface->format->Amask) { | |
347 if ( SDL_RLESurface(surface) == 0 ) | |
348 surface->map->sw_blit = SDL_RLEAlphaBlit; | |
349 } | |
350 } | |
351 | |
352 if ( surface->map->sw_blit == NULL ) { | |
353 surface->map->sw_blit = SDL_SoftBlit; | |
354 } | |
355 return(0); | |
356 } | |
357 |