demux_mkv: fix minor memory leak
[mplayer.git] / libvo / osd.c
blobf0df21536b11e4f8b215cef75aac41ccf4459edb
1 /*
2 * generic alpha renderers for all YUV modes and RGB depths
3 * These are "reference implementations", should be optimized later (MMX, etc).
4 * templating code by Michael Niedermayer (michaelni@gmx.at)
6 * This file is part of MPlayer.
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "config.h"
24 #include "osd.h"
25 #include "mp_msg.h"
26 #include <inttypes.h>
27 #include "cpudetect.h"
29 #if ARCH_X86
30 static const uint64_t bFF __attribute__((aligned(8))) = 0xFFFFFFFFFFFFFFFFULL;
31 static const unsigned long long mask24lh __attribute__((aligned(8))) = 0xFFFF000000000000ULL;
32 static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FFFFFFFFFFFFULL;
33 #endif
35 //Note: we have C, X86-nommx, MMX, MMX2, 3DNOW version therse no 3DNOW+MMX2 one
36 //Plain C versions
37 #if !HAVE_MMX || CONFIG_RUNTIME_CPUDETECT
38 #define COMPILE_C
39 #endif
41 #if ARCH_X86
43 #if (HAVE_MMX && !HAVE_AMD3DNOW && !HAVE_MMX2) || CONFIG_RUNTIME_CPUDETECT
44 #define COMPILE_MMX
45 #endif
47 #if HAVE_MMX2 || CONFIG_RUNTIME_CPUDETECT
48 #define COMPILE_MMX2
49 #endif
51 #if (HAVE_AMD3DNOW && !HAVE_MMX2) || CONFIG_RUNTIME_CPUDETECT
52 #define COMPILE_3DNOW
53 #endif
55 #endif /* ARCH_X86 */
57 #undef HAVE_MMX
58 #undef HAVE_MMX2
59 #undef HAVE_AMD3DNOW
60 #define HAVE_MMX 0
61 #define HAVE_MMX2 0
62 #define HAVE_AMD3DNOW 0
64 #if ! ARCH_X86
66 #ifdef COMPILE_C
67 #undef HAVE_MMX
68 #undef HAVE_MMX2
69 #undef HAVE_AMD3DNOW
70 #define HAVE_MMX 0
71 #define HAVE_MMX2 0
72 #define HAVE_AMD3DNOW 0
73 #define RENAME(a) a ## _C
74 #include "osd_template.c"
75 #endif
77 #else
79 //X86 noMMX versions
80 #ifdef COMPILE_C
81 #undef RENAME
82 #undef HAVE_MMX
83 #undef HAVE_MMX2
84 #undef HAVE_AMD3DNOW
85 #define HAVE_MMX 0
86 #define HAVE_MMX2 0
87 #define HAVE_AMD3DNOW 0
88 #define RENAME(a) a ## _X86
89 #include "osd_template.c"
90 #endif
92 //MMX versions
93 #ifdef COMPILE_MMX
94 #undef RENAME
95 #undef HAVE_MMX
96 #undef HAVE_MMX2
97 #undef HAVE_AMD3DNOW
98 #define HAVE_MMX 1
99 #define HAVE_MMX2 0
100 #define HAVE_AMD3DNOW 0
101 #define RENAME(a) a ## _MMX
102 #include "osd_template.c"
103 #endif
105 //MMX2 versions
106 #ifdef COMPILE_MMX2
107 #undef RENAME
108 #undef HAVE_MMX
109 #undef HAVE_MMX2
110 #undef HAVE_AMD3DNOW
111 #define HAVE_MMX 1
112 #define HAVE_MMX2 1
113 #define HAVE_AMD3DNOW 0
114 #define RENAME(a) a ## _MMX2
115 #include "osd_template.c"
116 #endif
118 //3DNOW versions
119 #ifdef COMPILE_3DNOW
120 #undef RENAME
121 #undef HAVE_MMX
122 #undef HAVE_MMX2
123 #undef HAVE_AMD3DNOW
124 #define HAVE_MMX 1
125 #define HAVE_MMX2 0
126 #define HAVE_AMD3DNOW 1
127 #define RENAME(a) a ## _3DNow
128 #include "osd_template.c"
129 #endif
131 #endif /* ARCH_X86 */
133 void vo_draw_alpha_yv12(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
134 #if CONFIG_RUNTIME_CPUDETECT
135 #if ARCH_X86
136 // ordered by speed / fastest first
137 if(gCpuCaps.hasMMX2)
138 vo_draw_alpha_yv12_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
139 else if(gCpuCaps.has3DNow)
140 vo_draw_alpha_yv12_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
141 else if(gCpuCaps.hasMMX)
142 vo_draw_alpha_yv12_MMX(w, h, src, srca, srcstride, dstbase, dststride);
143 else
144 vo_draw_alpha_yv12_X86(w, h, src, srca, srcstride, dstbase, dststride);
145 #else
146 vo_draw_alpha_yv12_C(w, h, src, srca, srcstride, dstbase, dststride);
147 #endif
148 #else //CONFIG_RUNTIME_CPUDETECT
149 #if HAVE_MMX2
150 vo_draw_alpha_yv12_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
151 #elif HAVE_AMD3DNOW
152 vo_draw_alpha_yv12_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
153 #elif HAVE_MMX
154 vo_draw_alpha_yv12_MMX(w, h, src, srca, srcstride, dstbase, dststride);
155 #elif ARCH_X86
156 vo_draw_alpha_yv12_X86(w, h, src, srca, srcstride, dstbase, dststride);
157 #else
158 vo_draw_alpha_yv12_C(w, h, src, srca, srcstride, dstbase, dststride);
159 #endif
160 #endif //!CONFIG_RUNTIME_CPUDETECT
163 void vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
164 #if CONFIG_RUNTIME_CPUDETECT
165 #if ARCH_X86
166 // ordered by speed / fastest first
167 if(gCpuCaps.hasMMX2)
168 vo_draw_alpha_yuy2_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
169 else if(gCpuCaps.has3DNow)
170 vo_draw_alpha_yuy2_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
171 else if(gCpuCaps.hasMMX)
172 vo_draw_alpha_yuy2_MMX(w, h, src, srca, srcstride, dstbase, dststride);
173 else
174 vo_draw_alpha_yuy2_X86(w, h, src, srca, srcstride, dstbase, dststride);
175 #else
176 vo_draw_alpha_yuy2_C(w, h, src, srca, srcstride, dstbase, dststride);
177 #endif
178 #else //CONFIG_RUNTIME_CPUDETECT
179 #if HAVE_MMX2
180 vo_draw_alpha_yuy2_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
181 #elif HAVE_AMD3DNOW
182 vo_draw_alpha_yuy2_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
183 #elif HAVE_MMX
184 vo_draw_alpha_yuy2_MMX(w, h, src, srca, srcstride, dstbase, dststride);
185 #elif ARCH_X86
186 vo_draw_alpha_yuy2_X86(w, h, src, srca, srcstride, dstbase, dststride);
187 #else
188 vo_draw_alpha_yuy2_C(w, h, src, srca, srcstride, dstbase, dststride);
189 #endif
190 #endif //!CONFIG_RUNTIME_CPUDETECT
193 void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
194 #if CONFIG_RUNTIME_CPUDETECT
195 #if ARCH_X86
196 // ordered by speed / fastest first
197 if(gCpuCaps.hasMMX2)
198 vo_draw_alpha_rgb24_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
199 else if(gCpuCaps.has3DNow)
200 vo_draw_alpha_rgb24_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
201 else if(gCpuCaps.hasMMX)
202 vo_draw_alpha_rgb24_MMX(w, h, src, srca, srcstride, dstbase, dststride);
203 else
204 vo_draw_alpha_rgb24_X86(w, h, src, srca, srcstride, dstbase, dststride);
205 #else
206 vo_draw_alpha_rgb24_C(w, h, src, srca, srcstride, dstbase, dststride);
207 #endif
208 #else //CONFIG_RUNTIME_CPUDETECT
209 #if HAVE_MMX2
210 vo_draw_alpha_rgb24_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
211 #elif HAVE_AMD3DNOW
212 vo_draw_alpha_rgb24_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
213 #elif HAVE_MMX
214 vo_draw_alpha_rgb24_MMX(w, h, src, srca, srcstride, dstbase, dststride);
215 #elif ARCH_X86
216 vo_draw_alpha_rgb24_X86(w, h, src, srca, srcstride, dstbase, dststride);
217 #else
218 vo_draw_alpha_rgb24_C(w, h, src, srca, srcstride, dstbase, dststride);
219 #endif
220 #endif //!CONFIG_RUNTIME_CPUDETECT
223 void vo_draw_alpha_rgb32(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
224 #if CONFIG_RUNTIME_CPUDETECT
225 #if ARCH_X86
226 // ordered by speed / fastest first
227 if(gCpuCaps.hasMMX2)
228 vo_draw_alpha_rgb32_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
229 else if(gCpuCaps.has3DNow)
230 vo_draw_alpha_rgb32_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
231 else if(gCpuCaps.hasMMX)
232 vo_draw_alpha_rgb32_MMX(w, h, src, srca, srcstride, dstbase, dststride);
233 else
234 vo_draw_alpha_rgb32_X86(w, h, src, srca, srcstride, dstbase, dststride);
235 #else
236 vo_draw_alpha_rgb32_C(w, h, src, srca, srcstride, dstbase, dststride);
237 #endif
238 #else //CONFIG_RUNTIME_CPUDETECT
239 #if HAVE_MMX2
240 vo_draw_alpha_rgb32_MMX2(w, h, src, srca, srcstride, dstbase, dststride);
241 #elif HAVE_AMD3DNOW
242 vo_draw_alpha_rgb32_3DNow(w, h, src, srca, srcstride, dstbase, dststride);
243 #elif HAVE_MMX
244 vo_draw_alpha_rgb32_MMX(w, h, src, srca, srcstride, dstbase, dststride);
245 #elif ARCH_X86
246 vo_draw_alpha_rgb32_X86(w, h, src, srca, srcstride, dstbase, dststride);
247 #else
248 vo_draw_alpha_rgb32_C(w, h, src, srca, srcstride, dstbase, dststride);
249 #endif
250 #endif //!CONFIG_RUNTIME_CPUDETECT
253 void vo_draw_alpha_init(void){
254 //FIXME the optimized stuff is a lie for 15/16bpp as they aren't optimized yet
255 if( mp_msg_test(MSGT_OSD,MSGL_V) )
257 #if CONFIG_RUNTIME_CPUDETECT
258 #if ARCH_X86
259 // ordered per speed fasterst first
260 if(gCpuCaps.hasMMX2)
261 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay\n");
262 else if(gCpuCaps.has3DNow)
263 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit 3DNow) Optimized OnScreenDisplay\n");
264 else if(gCpuCaps.hasMMX)
265 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX Optimized OnScreenDisplay\n");
266 else
267 mp_msg(MSGT_OSD,MSGL_INFO,"Using X86 Optimized OnScreenDisplay\n");
268 #else
269 mp_msg(MSGT_OSD,MSGL_INFO,"Using Unoptimized OnScreenDisplay\n");
270 #endif
271 #else //CONFIG_RUNTIME_CPUDETECT
272 #if HAVE_MMX2
273 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay\n");
274 #elif HAVE_AMD3DNOW
275 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX (with tiny bit 3DNow) Optimized OnScreenDisplay\n");
276 #elif HAVE_MMX
277 mp_msg(MSGT_OSD,MSGL_INFO,"Using MMX Optimized OnScreenDisplay\n");
278 #elif ARCH_X86
279 mp_msg(MSGT_OSD,MSGL_INFO,"Using X86 Optimized OnScreenDisplay\n");
280 #else
281 mp_msg(MSGT_OSD,MSGL_INFO,"Using Unoptimized OnScreenDisplay\n");
282 #endif
283 #endif //!CONFIG_RUNTIME_CPUDETECT
287 void vo_draw_alpha_rgb12(int w, int h, unsigned char* src, unsigned char *srca,
288 int srcstride, unsigned char* dstbase, int dststride) {
289 int y;
290 for (y = 0; y < h; y++) {
291 register unsigned short *dst = (unsigned short*) dstbase;
292 register int x;
293 for (x = 0; x < w; x++) {
294 if(srca[x]){
295 unsigned char r = dst[x] & 0x0F;
296 unsigned char g = (dst[x] >> 4) & 0x0F;
297 unsigned char b = (dst[x] >> 8) & 0x0F;
298 r = (((r*srca[x]) >> 4) + src[x]) >> 4;
299 g = (((g*srca[x]) >> 4) + src[x]) >> 4;
300 b = (((b*srca[x]) >> 4) + src[x]) >> 4;
301 dst[x] = (b << 8) | (g << 4) | r;
304 src += srcstride;
305 srca += srcstride;
306 dstbase += dststride;
308 return;
311 void vo_draw_alpha_rgb15(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
312 int y;
313 for(y=0;y<h;y++){
314 register unsigned short *dst = (unsigned short*) dstbase;
315 register int x;
316 for(x=0;x<w;x++){
317 if(srca[x]){
318 unsigned char r=dst[x]&0x1F;
319 unsigned char g=(dst[x]>>5)&0x1F;
320 unsigned char b=(dst[x]>>10)&0x1F;
321 r=(((r*srca[x])>>5)+src[x])>>3;
322 g=(((g*srca[x])>>5)+src[x])>>3;
323 b=(((b*srca[x])>>5)+src[x])>>3;
324 dst[x]=(b<<10)|(g<<5)|r;
327 src+=srcstride;
328 srca+=srcstride;
329 dstbase+=dststride;
331 return;
334 void vo_draw_alpha_rgb16(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
335 int y;
336 for(y=0;y<h;y++){
337 register unsigned short *dst = (unsigned short*) dstbase;
338 register int x;
339 for(x=0;x<w;x++){
340 if(srca[x]){
341 unsigned char r=dst[x]&0x1F;
342 unsigned char g=(dst[x]>>5)&0x3F;
343 unsigned char b=(dst[x]>>11)&0x1F;
344 r=(((r*srca[x])>>5)+src[x])>>3;
345 g=(((g*srca[x])>>6)+src[x])>>2;
346 b=(((b*srca[x])>>5)+src[x])>>3;
347 dst[x]=(b<<11)|(g<<5)|r;
350 src+=srcstride;
351 srca+=srcstride;
352 dstbase+=dststride;
354 return;