Mercurial > sdl-ios-xcode
annotate src/video/x11/SDL_x11yuv.c @ 637:6862d4294870
te: 27 Jun 2003 21:16:01 +0100
From: Alan Swanson
Subject: [SDL] New XFree 4.3 Video Mode Patch
The current patch to fix the issues with XFree 4.3 it is a bit of
overkill to a simple problem. Default screen settings should be set in
X, not selected by SDL with environment variables. Any program or user
using non-standard or unset display modes get what they deserve :-)
If you look at the unsorted list of modes returned by X, here's mine;
1280 x 1024 @ 85.0 >
1024 x 768 @ 100.3 > USER
800 x 600 @ 125.5 > SET
640 x 480 @ 124.9 >
1280 x 1024 @ 75.0 ]
1280 x 1024 @ 60.0 ]
1280 x 960 @ 85.0 ] X11
1280 x 960 @ 60.0 ] AUTO
1152 x 864 @ 75.0 ]
1152 x 768 @ 54.8 ]
960 x 720 @ 120.0 ]
...
640 x 400 @ 85.1 ] 256k
576 x 432 @ 150.0 ] 249k PIXEL
640 x 350 @ 85.1 ] 224k COUNT
576 x 384 @ 109.6 ] 221k
...
The user set modes come first followed by X set modes which are ordered
by decreasing number of pixels and refresh.
The reason why every other library or program not using SDL was working
is due to SDL scanning the modes in reverse getting X11 provided modes
modes with the lowest refresh.
The solution is to scan forward for the first user set mode or highest X
mode. The qsort still keeps user set modes above higher refresh modes
added by X.
For the best match we still reverse search for the nearest larger size
and then try to find a higher version of it.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 28 Jun 2003 17:16:52 +0000 |
parents | 95aa4041e7f9 |
children | e3d0517bf67e |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
292
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:
182
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* This is the XFree86 Xv extension implementation of YUV video overlays */ | |
29 | |
30 #ifdef XFREE86_XV | |
31 | |
32 #include <stdlib.h> | |
33 #include <string.h> | |
34 #include <X11/Xlib.h> | |
35 #include <sys/ipc.h> | |
36 #include <sys/shm.h> | |
37 #include <X11/extensions/XShm.h> | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
38 #include <XFree86/extensions/Xvlib.h> |
0 | 39 |
40 #include "SDL_error.h" | |
41 #include "SDL_video.h" | |
42 #include "SDL_x11yuv_c.h" | |
43 #include "SDL_yuvfuncs.h" | |
44 | |
45 #define XFREE86_REFRESH_HACK | |
46 #ifdef XFREE86_REFRESH_HACK | |
47 #include "SDL_x11image_c.h" | |
48 #endif | |
49 | |
50 /* Workaround when pitch != width */ | |
51 #define PITCH_WORKAROUND | |
52 | |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
53 /* Fix for the NVidia GeForce 2 - use the last available adaptor */ |
341
6ca967a46bf1
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
297
diff
changeset
|
54 /*#define USE_LAST_ADAPTOR*/ /* Apparently the NVidia drivers are fixed */ |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
55 |
0 | 56 /* The functions used to manipulate software video overlays */ |
57 static struct private_yuvhwfuncs x11_yuvfuncs = { | |
58 X11_LockYUVOverlay, | |
59 X11_UnlockYUVOverlay, | |
60 X11_DisplayYUVOverlay, | |
61 X11_FreeYUVOverlay | |
62 }; | |
63 | |
64 struct private_yuvhwdata { | |
65 int port; | |
66 XShmSegmentInfo yuvshm; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
67 SDL_NAME(XvImage) *image; |
0 | 68 }; |
69 | |
70 | |
71 SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | |
72 { | |
73 SDL_Overlay *overlay; | |
74 struct private_yuvhwdata *hwdata; | |
75 int xv_port; | |
76 int i, j, k; | |
77 int adaptors; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
78 SDL_NAME(XvAdaptorInfo) *ainfo; |
0 | 79 XShmSegmentInfo *yuvshm; |
80 | |
81 /* Look for the XVideo extension with a valid port for this format */ | |
82 xv_port = -1; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
83 if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) && |
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
84 (Success == SDL_NAME(XvQueryAdaptors)(GFX_Display, |
0 | 85 RootWindow(GFX_Display, SDL_Screen), |
86 &adaptors, &ainfo)) ) { | |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
87 #ifdef USE_LAST_ADAPTOR |
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
88 for ( i=0; i < adaptors; ++i ) { |
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
89 #else |
0 | 90 for ( i=0; (i < adaptors) && (xv_port == -1); ++i ) { |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
91 #endif /* USE_LAST_ADAPTOR */ |
0 | 92 /* Check to see if the visual can be used */ |
93 if ( BUGGY_XFREE86(<=, 4001) ) { | |
94 int visual_ok = 0; | |
95 for ( j=0; j<ainfo[i].num_formats; ++j ) { | |
96 if ( ainfo[i].formats[j].visual_id == | |
97 SDL_Visual->visualid ) { | |
98 visual_ok = 1; | |
99 break; | |
100 } | |
101 } | |
102 if ( ! visual_ok ) { | |
103 continue; | |
104 } | |
105 } | |
106 if ( (ainfo[i].type & XvInputMask) && | |
107 (ainfo[i].type & XvImageMask) ) { | |
108 int num_formats; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
109 SDL_NAME(XvImageFormatValues) *formats; |
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
110 formats = SDL_NAME(XvListImageFormats)(GFX_Display, |
0 | 111 ainfo[i].base_id, &num_formats); |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
112 #ifdef USE_LAST_ADAPTOR |
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
113 for ( j=0; j < num_formats; ++j ) { |
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
114 #else |
0 | 115 for ( j=0; (j < num_formats) && (xv_port == -1); ++j ) { |
182
d4ebd1bbea9a
Fix XVideo on GeForce by using last available adaptor
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
116 #endif /* USE_LAST_ADAPTOR */ |
0 | 117 if ( (Uint32)formats[j].id == format ) { |
118 for ( k=0; k < ainfo[i].num_ports; ++k ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
119 if ( Success == SDL_NAME(XvGrabPort)(GFX_Display, ainfo[i].base_id+k, CurrentTime) ) { |
0 | 120 xv_port = ainfo[i].base_id+k; |
121 break; | |
122 } | |
123 } | |
124 } | |
125 } | |
410
365f57b7c4ac
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
409
diff
changeset
|
126 if ( formats ) { |
365f57b7c4ac
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
409
diff
changeset
|
127 XFree(formats); |
365f57b7c4ac
*** empty log message ***
Sam Lantinga <slouken@libsdl.org>
parents:
409
diff
changeset
|
128 } |
0 | 129 } |
130 } | |
409
1c3cf7231cd4
Fixed memory leaks in YUV code
Sam Lantinga <slouken@libsdl.org>
parents:
341
diff
changeset
|
131 SDL_NAME(XvFreeAdaptorInfo)(ainfo); |
0 | 132 } |
429
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
133 |
434
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
134 #if 0 |
429
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
135 /* |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
136 * !!! FIXME: |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
137 * "Here are some diffs for X11 and yuv. Note that the last part 2nd |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
138 * diff should probably be a new call to XvQueryAdaptorFree with ainfo |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
139 * and the number of adaptors, instead of the loop through like I did." |
434
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
140 * |
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
141 * ACHTUNG: This is broken! It looks like XvFreeAdaptorInfo does this |
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
142 * for you, so we end up with a double-free. I need to look at this |
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
143 * more closely... --ryan. |
429
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
144 */ |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
145 for ( i=0; i < adaptors; ++i ) { |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
146 if (ainfo[i].name != NULL) Xfree(ainfo[i].name); |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
147 if (ainfo[i].formats != NULL) Xfree(ainfo[i].formats); |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
148 } |
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
149 Xfree(ainfo); |
434
ed58b98c0d9d
Commented double-free buggy code. Will examine more closely later.
Ryan C. Gordon <icculus@icculus.org>
parents:
429
diff
changeset
|
150 #endif |
429
c1666427297c
Memory leak fixes by Bill May.
Ryan C. Gordon <icculus@icculus.org>
parents:
410
diff
changeset
|
151 |
0 | 152 if ( xv_port == -1 ) { |
153 SDL_SetError("No available video ports for requested format"); | |
154 return(NULL); | |
155 } | |
156 | |
157 /* Create the overlay structure */ | |
158 overlay = (SDL_Overlay *)malloc(sizeof *overlay); | |
159 if ( overlay == NULL ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
160 SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); |
0 | 161 SDL_OutOfMemory(); |
162 return(NULL); | |
163 } | |
164 memset(overlay, 0, (sizeof *overlay)); | |
165 | |
166 /* Fill in the basic members */ | |
167 overlay->format = format; | |
168 overlay->w = width; | |
169 overlay->h = height; | |
170 | |
171 /* Set up the YUV surface function structure */ | |
172 overlay->hwfuncs = &x11_yuvfuncs; | |
173 overlay->hw_overlay = 1; | |
174 | |
175 /* Create the pixel data and lookup tables */ | |
176 hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata); | |
177 overlay->hwdata = hwdata; | |
178 if ( hwdata == NULL ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
179 SDL_NAME(XvUngrabPort)(GFX_Display, xv_port, CurrentTime); |
0 | 180 SDL_OutOfMemory(); |
181 SDL_FreeYUVOverlay(overlay); | |
182 return(NULL); | |
183 } | |
184 yuvshm = &hwdata->yuvshm; | |
185 memset(yuvshm, 0, sizeof(*yuvshm)); | |
186 hwdata->port = xv_port; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
187 hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, |
0 | 188 0, width, height, yuvshm); |
189 | |
190 #ifdef PITCH_WORKAROUND | |
191 if ( hwdata->image != NULL && hwdata->image->pitches[0] != width ) | |
192 { | |
193 /* Ajust overlay width according to pitch */ | |
194 switch (format) { | |
195 case SDL_YV12_OVERLAY: | |
196 case SDL_IYUV_OVERLAY: | |
197 width = hwdata->image->pitches[0]; | |
198 break; | |
199 case SDL_YUY2_OVERLAY: | |
200 case SDL_UYVY_OVERLAY: | |
201 case SDL_YVYU_OVERLAY: | |
202 width = hwdata->image->pitches[0] / 2; | |
203 break; | |
204 default: | |
205 /* We should never get here (caught above) */ | |
206 return(NULL); | |
207 } | |
208 | |
209 XFree(hwdata->image); | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
210 hwdata->image = SDL_NAME(XvShmCreateImage)(GFX_Display, xv_port, format, |
0 | 211 0, width, height, yuvshm); |
212 } | |
213 #endif | |
214 | |
215 if ( hwdata->image == NULL ) { | |
216 SDL_OutOfMemory(); | |
217 SDL_FreeYUVOverlay(overlay); | |
218 return(NULL); | |
219 } | |
220 yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size, | |
221 IPC_CREAT | 0777); | |
222 if ( yuvshm->shmid < 0 ) { | |
223 SDL_SetError("Unable to get %d bytes shared memory", | |
224 hwdata->image->data_size); | |
225 SDL_FreeYUVOverlay(overlay); | |
226 return(NULL); | |
227 } | |
228 yuvshm->shmaddr = (char *) shmat(yuvshm->shmid, 0, 0); | |
229 yuvshm->readOnly = False; | |
230 hwdata->image->data = yuvshm->shmaddr; | |
231 | |
232 XShmAttach(GFX_Display, yuvshm); | |
233 XSync(GFX_Display, False); | |
234 shmctl(yuvshm->shmid, IPC_RMID, 0); | |
235 | |
236 /* Find the pitch and offset values for the overlay */ | |
237 overlay->planes = hwdata->image->num_planes; | |
238 overlay->pitches = (Uint16 *)malloc(overlay->planes * sizeof(Uint16)); | |
239 overlay->pixels = (Uint8 **)malloc(overlay->planes * sizeof(Uint8 *)); | |
240 if ( !overlay->pitches || !overlay->pixels ) { | |
241 SDL_OutOfMemory(); | |
242 SDL_FreeYUVOverlay(overlay); | |
243 return(NULL); | |
244 } | |
245 for ( i=0; i<overlay->planes; ++i ) { | |
246 overlay->pitches[i] = hwdata->image->pitches[i]; | |
247 overlay->pixels[i] = (Uint8 *)hwdata->image->data + | |
248 hwdata->image->offsets[i]; | |
249 } | |
250 | |
251 #ifdef XFREE86_REFRESH_HACK | |
252 /* Work around an XFree86 X server bug (?) | |
253 We can't perform normal updates in windows that have video | |
254 being output to them. See SDL_x11image.c for more details. | |
255 */ | |
256 X11_DisableAutoRefresh(this); | |
257 #endif | |
258 | |
259 /* We're all done.. */ | |
260 return(overlay); | |
261 } | |
262 | |
263 int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
264 { | |
265 return(0); | |
266 } | |
267 | |
268 void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) | |
269 { | |
270 return; | |
271 } | |
272 | |
273 int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) | |
274 { | |
275 struct private_yuvhwdata *hwdata; | |
276 | |
277 hwdata = overlay->hwdata; | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
278 SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, SDL_Window, SDL_GC, |
0 | 279 hwdata->image, 0, 0, overlay->w, overlay->h, |
280 dstrect->x, dstrect->y, dstrect->w, dstrect->h, False); | |
281 XSync(GFX_Display, False); | |
282 return(0); | |
283 } | |
284 | |
285 void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) | |
286 { | |
287 struct private_yuvhwdata *hwdata; | |
288 | |
289 hwdata = overlay->hwdata; | |
290 if ( hwdata ) { | |
292
eadc0746dfaf
Added SDL_LockRect() and SDL_UnlockRect()
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
291 SDL_NAME(XvUngrabPort)(GFX_Display, hwdata->port, CurrentTime); |
0 | 292 if ( hwdata->yuvshm.shmaddr ) { |
293 XShmDetach(GFX_Display, &hwdata->yuvshm); | |
294 shmdt(hwdata->yuvshm.shmaddr); | |
295 } | |
296 if ( hwdata->image ) { | |
297 XFree(hwdata->image); | |
298 } | |
299 free(hwdata); | |
300 } | |
301 if ( overlay->pitches ) { | |
302 free(overlay->pitches); | |
303 overlay->pitches = NULL; | |
304 } | |
305 if ( overlay->pixels ) { | |
306 free(overlay->pixels); | |
307 overlay->pixels = NULL; | |
308 } | |
309 #ifdef XFREE86_REFRESH_HACK | |
310 X11_EnableAutoRefresh(this); | |
311 #endif | |
312 } | |
313 | |
314 #endif /* XFREE86_XV */ |