[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60528] trunk/blender/intern/ghost/intern/ GHOST_WindowX11.cpp: Fix crash starting game engine on linux

Sergey Sharybin sergey.vfx at gmail.com
Thu Oct 3 15:15:54 CEST 2013


Revision: 60528
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60528
Author:   nazgul
Date:     2013-10-03 13:15:53 +0000 (Thu, 03 Oct 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp	2013-10-03 12:22:44 UTC (rev 60527)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp	2013-10-03 13:15:53 UTC (rev 60528)
@@ -65,6 +65,14 @@
 	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 @@
 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;




More information about the Bf-blender-cvs mailing list