Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-10-03 17:15:53 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-10-03 17:15:53 +0400
commit94fdaa5d41ecc33f48bec6d2094e67f533a0e5de (patch)
tree655429bfbb93f3c2a21c237fd81d3fa889e3a0a3 /intern/ghost
parent9b1be7ce93b8c40bac0da2743009399f732801a8 (diff)
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.
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp61
1 files changed, 59 insertions, 2 deletions
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 25c74a0a6cb..3e6e1cd1a94 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -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;