forked from bartvdbraak/blender
Fix crash starting game engine on linux
Issue was caused by bug in mesa #54080 which makes glXQueryDrawable fail with GLXBadDrawable for any request with direct context. Worked around by temporary overriding X error handling when getting old interval value and disablingintervals extension if this query fails. Also added check for glXSwapIntervalEXT which is apparently NULL here with GLX_EXT_swap_control=1.
This commit is contained in:
parent
9b1be7ce93
commit
94fdaa5d41
@ -65,6 +65,14 @@ typedef struct {
|
||||
long input_mode;
|
||||
} MotifWmHints;
|
||||
|
||||
// Workaround for MESA bug #54080
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=54080()
|
||||
#define SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
static bool g_swap_interwal_disabled = false;
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
|
||||
|
||||
@ -1519,18 +1527,67 @@ endFullScreen() const
|
||||
GHOST_TSuccess
|
||||
GHOST_WindowX11::
|
||||
setSwapInterval(int interval) {
|
||||
if (!GLX_EXT_swap_control)
|
||||
if (!GLX_EXT_swap_control || !glXSwapIntervalEXT
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
|| g_swap_interwal_disabled
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
)
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
glXSwapIntervalEXT(m_display, m_window, interval);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
static int QueryDrawable_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent)
|
||||
{
|
||||
fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
|
||||
theEvent->error_code, theEvent->request_code);
|
||||
if (!g_swap_interwal_disabled) {
|
||||
fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
|
||||
g_swap_interwal_disabled = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int QueryDrawable_ApplicationIOErrorHandler(Display *display)
|
||||
{
|
||||
fprintf(stderr, "Ignoring Xlib error: error IO\n");
|
||||
if (!g_swap_interwal_disabled) {
|
||||
fprintf(stderr, "Disabling SWAP INTERVALS extension\n");
|
||||
g_swap_interwal_disabled = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
int
|
||||
GHOST_WindowX11::
|
||||
getSwapInterval() {
|
||||
if (GLX_EXT_swap_control) {
|
||||
unsigned int value;
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
/* XXX: Current MESA driver will give GLXBadDrawable for all
|
||||
* the glXQueryDrawable requests with direct contexts.
|
||||
*
|
||||
* To prevent crashes and unexpected behaviors, we will
|
||||
* disable swap interwals extension if query fails here.
|
||||
* (because if we will override interval without having
|
||||
* old value we couldn't restore it properly).
|
||||
*/
|
||||
XErrorHandler old_handler = XSetErrorHandler(QueryDrawable_ApplicationErrorHandler);
|
||||
XIOErrorHandler old_handler_io = XSetIOErrorHandler(QueryDrawable_ApplicationIOErrorHandler);
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
unsigned int value = 0;
|
||||
glXQueryDrawable(m_display, m_window, GLX_SWAP_INTERVAL_EXT, &value);
|
||||
|
||||
#ifdef SWAP_INTERVALS_WORKAROUND
|
||||
/* Restore handler */
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
(void) XSetIOErrorHandler(old_handler_io);
|
||||
#endif // SWAP_INTERVALS_WORKAROUND
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user