Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11yuv.c @ 4106:12bb6311fd5d SDL-1.2
Hans de Goede fixed bug #495
When running boswars: http://www.boswars.org/ on a machine with intel
integrathed graphics it crashes when it tries to play the initial theora
splashscreen video:
X Error of failed request: BadAlloc (insufficient resources for operation)
Major opcode of failed request: 140 (XVideo)
Minor opcode of failed request: 19 ()
Serial number of failed request: 25
Current serial number in output stream: 26
boswars: xcb_xlib.c:41: xcb_xlib_lock: Assertion `!c->xlib.lock' failed.
Aborted
I recognized this problem from a few years back, when I encountered it while
working on the Xv blitter for xmame. The problem is that for some reason
creation the Xvport and XvImage succeeds, and failure (lack of resources / hw
capability?) is only indicated during the first XvPut[Shm]Image. I've written a
patch for SDL using the work around for this I developed for xmame (and which
is still used successfully in xmame after many years of usage).
I'll admit it isn't very pretty, but after investigating several possibilities
this was the best option, any other fixes would need changes to the SDL api and
abi.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 29 Dec 2007 02:23:48 +0000 |
parents | 51038e80ae59 |
children | a1b03ba2fcd0 |
comparison
equal
deleted
inserted
replaced
4105:84882a89ca50 | 4106:12bb6311fd5d |
---|---|
41 #include "SDL_x11image_c.h" | 41 #include "SDL_x11image_c.h" |
42 #endif | 42 #endif |
43 | 43 |
44 /* Workaround when pitch != width */ | 44 /* Workaround when pitch != width */ |
45 #define PITCH_WORKAROUND | 45 #define PITCH_WORKAROUND |
46 | |
47 /* Workaround intel i810 video overlay waiting with failing until the | |
48 first Xv[Shm]PutImage call <sigh> */ | |
49 #define INTEL_XV_BADALLOC_WORKAROUND | |
46 | 50 |
47 /* Fix for the NVidia GeForce 2 - use the last available adaptor */ | 51 /* Fix for the NVidia GeForce 2 - use the last available adaptor */ |
48 /*#define USE_LAST_ADAPTOR*/ /* Apparently the NVidia drivers are fixed */ | 52 /*#define USE_LAST_ADAPTOR*/ /* Apparently the NVidia drivers are fixed */ |
49 | 53 |
50 /* The functions used to manipulate software video overlays */ | 54 /* The functions used to manipulate software video overlays */ |
88 return(0); | 92 return(0); |
89 } else | 93 } else |
90 return(X_handler(d,e)); | 94 return(X_handler(d,e)); |
91 } | 95 } |
92 | 96 |
97 #ifdef INTEL_XV_BADALLOC_WORKAROUND | |
98 static int intel_errhandler(Display *d, XErrorEvent *e) | |
99 { | |
100 if ( e->error_code == BadAlloc ) { | |
101 xv_error = True; | |
102 return(0); | |
103 } else | |
104 return(X_handler(d,e)); | |
105 } | |
106 | |
107 static void X11_ClearYUVOverlay(SDL_Overlay *overlay) | |
108 { | |
109 int x,y; | |
110 | |
111 switch (overlay->format) | |
112 { | |
113 case SDL_YV12_OVERLAY: | |
114 case SDL_IYUV_OVERLAY: | |
115 for (y = 0; y < overlay->h; y++) | |
116 memset(overlay->pixels[0] + y * overlay->pitches[0], | |
117 0, overlay->w); | |
118 | |
119 for (y = 0; y < (overlay->h / 2); y++) | |
120 { | |
121 memset(overlay->pixels[1] + y * overlay->pitches[1], | |
122 -128, overlay->w / 2); | |
123 memset(overlay->pixels[2] + y * overlay->pitches[2], | |
124 -128, overlay->w / 2); | |
125 } | |
126 break; | |
127 case SDL_YUY2_OVERLAY: | |
128 case SDL_YVYU_OVERLAY: | |
129 for (y = 0; y < overlay->h; y++) | |
130 { | |
131 for (x = 0; x < overlay->w; x += 2) | |
132 { | |
133 Uint8 *pixel_pair = overlay->pixels[0] + | |
134 y * overlay->pitches[0] + x * 2; | |
135 pixel_pair[0] = 0; | |
136 pixel_pair[1] = -128; | |
137 pixel_pair[2] = 0; | |
138 pixel_pair[3] = -128; | |
139 } | |
140 } | |
141 break; | |
142 case SDL_UYVY_OVERLAY: | |
143 for (y = 0; y < overlay->h; y++) | |
144 { | |
145 for (x = 0; x < overlay->w; x += 2) | |
146 { | |
147 Uint8 *pixel_pair = overlay->pixels[0] + | |
148 y * overlay->pitches[0] + x * 2; | |
149 pixel_pair[0] = -128; | |
150 pixel_pair[1] = 0; | |
151 pixel_pair[2] = -128; | |
152 pixel_pair[3] = 0; | |
153 } | |
154 } | |
155 break; | |
156 } | |
157 } | |
158 #endif | |
159 | |
93 SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) | 160 SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) |
94 { | 161 { |
95 SDL_Overlay *overlay; | 162 SDL_Overlay *overlay; |
96 struct private_yuvhwdata *hwdata; | 163 struct private_yuvhwdata *hwdata; |
97 int xv_port; | 164 int xv_port; |
99 unsigned int adaptors; | 166 unsigned int adaptors; |
100 SDL_NAME(XvAdaptorInfo) *ainfo; | 167 SDL_NAME(XvAdaptorInfo) *ainfo; |
101 int bpp; | 168 int bpp; |
102 #ifndef NO_SHARED_MEMORY | 169 #ifndef NO_SHARED_MEMORY |
103 XShmSegmentInfo *yuvshm; | 170 XShmSegmentInfo *yuvshm; |
171 #endif | |
172 #ifdef INTEL_XV_BADALLOC_WORKAROUND | |
173 int intel_adapter = False; | |
104 #endif | 174 #endif |
105 | 175 |
106 /* Look for the XVideo extension with a valid port for this format */ | 176 /* Look for the XVideo extension with a valid port for this format */ |
107 xv_port = -1; | 177 xv_port = -1; |
108 if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) && | 178 if ( (Success == SDL_NAME(XvQueryExtension)(GFX_Display, &j, &j, &j, &j, &j)) && |
127 } | 197 } |
128 if ( ! visual_ok ) { | 198 if ( ! visual_ok ) { |
129 continue; | 199 continue; |
130 } | 200 } |
131 } | 201 } |
202 #ifdef INTEL_XV_BADALLOC_WORKAROUND | |
203 if ( !strcmp(ainfo[i].name, "Intel(R) Video Overla")) | |
204 intel_adapter = True; | |
205 else | |
206 intel_adapter = False; | |
207 #endif | |
132 if ( (ainfo[i].type & XvInputMask) && | 208 if ( (ainfo[i].type & XvInputMask) && |
133 (ainfo[i].type & XvImageMask) ) { | 209 (ainfo[i].type & XvImageMask) ) { |
134 int num_formats; | 210 int num_formats; |
135 SDL_NAME(XvImageFormatValues) *formats; | 211 SDL_NAME(XvImageFormatValues) *formats; |
136 formats = SDL_NAME(XvListImageFormats)(GFX_Display, | 212 formats = SDL_NAME(XvListImageFormats)(GFX_Display, |
338 being output to them. See SDL_x11image.c for more details. | 414 being output to them. See SDL_x11image.c for more details. |
339 */ | 415 */ |
340 X11_DisableAutoRefresh(this); | 416 X11_DisableAutoRefresh(this); |
341 #endif | 417 #endif |
342 | 418 |
419 #ifdef INTEL_XV_BADALLOC_WORKAROUND | |
420 /* HACK, GRRR sometimes (i810) creating the overlay succeeds, but the | |
421 first call to XvShm[Put]Image to a mapped window fails with: | |
422 "BadAlloc (insufficient resources for operation)". This happens with | |
423 certain formats when the XvImage is too large to the i810's liking. | |
424 | |
425 We work around this by doing a test XvShm[Put]Image with a black | |
426 Xv image, this may cause some flashing, so only do this check if we | |
427 are running on an intel Xv-adapter. */ | |
428 if (intel_adapter) | |
429 { | |
430 xv_error = False; | |
431 X_handler = XSetErrorHandler(intel_errhandler); | |
432 | |
433 X11_ClearYUVOverlay(overlay); | |
434 | |
435 /* We set the destination height and width to 1 pixel to avoid | |
436 putting a large black rectangle over the screen, thus | |
437 strongly reducing possible flashing. */ | |
438 #ifndef NO_SHARED_MEMORY | |
439 if ( hwdata->yuv_use_mitshm ) { | |
440 SDL_NAME(XvShmPutImage)(GFX_Display, hwdata->port, | |
441 SDL_Window, SDL_GC, | |
442 hwdata->image, | |
443 0, 0, overlay->w, overlay->h, | |
444 0, 0, 1, 1, False); | |
445 } | |
446 else | |
447 #endif | |
448 { | |
449 SDL_NAME(XvPutImage)(GFX_Display, hwdata->port, | |
450 SDL_Window, SDL_GC, | |
451 hwdata->image, | |
452 0, 0, overlay->w, overlay->h, | |
453 0, 0, 1, 1); | |
454 } | |
455 XSync(GFX_Display, False); | |
456 XSetErrorHandler(X_handler); | |
457 | |
458 if (xv_error) | |
459 { | |
460 X11_FreeYUVOverlay(this, overlay); | |
461 return NULL; | |
462 } | |
463 /* Repair the (1 pixel worth of) damage we've just done */ | |
464 X11_RefreshDisplay(this); | |
465 } | |
466 #endif | |
467 | |
343 /* We're all done.. */ | 468 /* We're all done.. */ |
344 return(overlay); | 469 return(overlay); |
345 } | 470 } |
346 | 471 |
347 int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay) | 472 int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay) |