[Bf-blender-cvs] [86e6d66] master: GHOST/X11: Support GLX-Context flags

Campbell Barton noreply at git.blender.org
Mon Jul 20 05:37:56 CEST 2015


Commit: 86e6d6695e815746e877f9a4234f6805d5a4c155
Author: Campbell Barton
Date:   Mon Jul 20 13:27:46 2015 +1000
Branches: master
https://developer.blender.org/rB86e6d6695e815746e877f9a4234f6805d5a4c155

GHOST/X11: Support GLX-Context flags

GHOST_ContextGLX was incomplete, ignoring profile-mask and profile-flags.

===================================================================

M	intern/ghost/intern/GHOST_ContextGLX.cpp
M	intern/ghost/intern/GHOST_ContextGLX.h
M	intern/ghost/intern/GHOST_SystemX11.h
M	intern/ghost/intern/GHOST_WindowX11.cpp

===================================================================

diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index c4e1346..487e493 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -152,7 +152,102 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
 	XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
 #endif
 
-	m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True);
+	/* needed so 'GLXEW_ARB_create_context' is valid */
+	initContextGLXEW();
+
+	if (GLXEW_ARB_create_context) {
+		int profileBitCore   = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+		int profileBitCompat = m_contextProfileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+
+#ifdef WITH_GLEW_ES
+		int profileBitES     = m_contextProfileMask & GLX_CONTEXT_ES_PROFILE_BIT_EXT;
+#endif
+
+		if (!GLXEW_ARB_create_context_profile && profileBitCore)
+			fprintf(stderr, "Warning! OpenGL core profile not available.\n");
+
+		if (!GLXEW_ARB_create_context_profile && profileBitCompat)
+			fprintf(stderr, "Warning! OpenGL compatibility profile not available.\n");
+
+#ifdef WITH_GLEW_ES
+		if (!GLXEW_EXT_create_context_es_profile && profileBitES && m_contextMajorVersion == 1)
+			fprintf(stderr, "Warning! OpenGL ES profile not available.\n");
+
+		if (!GLXEW_EXT_create_context_es2_profile && profileBitES && m_contextMajorVersion == 2)
+			fprintf(stderr, "Warning! OpenGL ES2 profile not available.\n");
+#endif
+
+		int profileMask = 0;
+
+		if (GLXEW_ARB_create_context_profile && profileBitCore)
+			profileMask |= profileBitCore;
+
+		if (GLXEW_ARB_create_context_profile && profileBitCompat)
+			profileMask |= profileBitCompat;
+
+#ifdef WITH_GLEW_ES
+		if (GLXEW_EXT_create_context_es_profile && profileBitES)
+			profileMask |= profileBitES;
+#endif
+
+		if (profileMask != m_contextProfileMask)
+			fprintf(stderr, "Warning! Ignoring untested OpenGL context profile mask bits.");
+
+
+		/* max 10 attributes plus terminator */
+		int attribs[11];
+		int i = 0;
+
+		if (profileMask) {
+			attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB;
+			attribs[i++] = profileMask;
+		}
+
+		if (m_contextMajorVersion != 0) {
+			attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
+			attribs[i++] = m_contextMajorVersion;
+		}
+
+		if (m_contextMinorVersion != 0) {
+			attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
+			attribs[i++] = m_contextMinorVersion;
+		}
+
+		if (m_contextFlags != 0) {
+			attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
+			attribs[i++] = m_contextFlags;
+		}
+
+		if (m_contextResetNotificationStrategy != 0) {
+			if (GLXEW_ARB_create_context_robustness) {
+				attribs[i++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
+				attribs[i++] = m_contextResetNotificationStrategy;
+			}
+			else {
+				fprintf(stderr, "Warning! Cannot set the reset notification strategy.");
+			}
+		}
+		attribs[i++] = 0;
+
+		/* Create a GL 3.x context */
+		GLXFBConfig *framebuffer_config = NULL;
+		{
+			int glx_attribs[64];
+			int fbcount = 0;
+
+			GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, true);
+
+			framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
+		}
+
+		if (framebuffer_config) {
+			m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs);
+		}
+	}
+	else {
+		/* Create legacy context */
+		m_context = glXCreateContext(m_display, m_visualInfo, s_sharedContext, True);
+	}
 
 	GHOST_TSuccess success;
 
@@ -164,16 +259,13 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
 
 		glXMakeCurrent(m_display, m_window, m_context);
 
-		// Seems that this has to be called after MakeCurrent,
-		// which means we cannot use glX extensions until after we create a context
-		initContextGLXEW();
-
 		initClearGL();
 		::glXSwapBuffers(m_display, m_window);
 
 		success = GHOST_kSuccess;
 	}
 	else {
+		/* freeing well clean up the context initialized above */
 		success = GHOST_kFailure;
 	}
 
@@ -223,3 +315,87 @@ GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut)
 		return GHOST_kFailure;
 	}
 }
+
+/**
+ * Utility function to get GLX attributes.
+ *
+ * \param for_fb_config: There are some small differences in
+ * #glXChooseVisual and #glXChooseFBConfig's attribute encoding.
+ *
+ * \note Similar to SDL's 'X11_GL_GetAttributes'
+ */
+int GHOST_X11_GL_GetAttributes(
+        int *attribs, int attribs_max,
+        int samples, bool is_stereo_visual,
+        bool for_fb_config)
+{
+	int i = 0;
+
+#ifdef GHOST_OPENGL_ALPHA
+	const bool need_alpha = true;
+#else
+	const bool need_alpha = false;
+#endif
+
+#ifdef GHOST_OPENGL_STENCIL
+	const bool need_stencil = true;
+#else
+	const bool need_stencil = false;
+#endif
+
+	if (is_stereo_visual) {
+		attribs[i++] = GLX_STEREO;
+		if (for_fb_config) {
+			attribs[i++] = True;
+		}
+	}
+
+	if (for_fb_config) {
+		attribs[i++] = GLX_RENDER_TYPE;
+		attribs[i++] = GLX_RGBA_BIT;
+	}
+	else {
+		attribs[i++] = GLX_RGBA;
+	}
+
+	attribs[i++] = GLX_DOUBLEBUFFER;
+	if (for_fb_config) {
+		attribs[i++] = True;
+	}
+
+	attribs[i++] = GLX_RED_SIZE;
+	attribs[i++] = True;
+
+	attribs[i++] = GLX_BLUE_SIZE;
+	attribs[i++] = True;
+
+	attribs[i++] = GLX_GREEN_SIZE;
+	attribs[i++] = True;
+
+	attribs[i++] = GLX_DEPTH_SIZE;
+	attribs[i++] = True;
+
+	if (need_alpha) {
+		attribs[i++] = GLX_ALPHA_SIZE;
+		attribs[i++] = True;
+	}
+
+	if (need_stencil) {
+		attribs[i++] = GLX_STENCIL_SIZE;
+		attribs[i++] = True;
+	}
+
+	if (samples) {
+		attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
+		attribs[i++] = True;
+
+		attribs[i++] = GLX_SAMPLES_ARB;
+		attribs[i++] = samples;
+	}
+
+	attribs[i++] = 0;
+
+	GHOST_ASSERT(i <= attribs_max, "attribute size too small");
+
+	return i;
+}
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index 04fe58a..8c2231a 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -54,7 +54,6 @@ extern "C" GLXEWContext *glxewContext;
 #define GHOST_OPENGL_GLX_RESET_NOTIFICATION_STRATEGY 0
 #endif
 
-
 class GHOST_ContextGLX : public GHOST_Context
 {
 public:
@@ -148,4 +147,10 @@ private:
 	static int        s_sharedCount;
 };
 
+/* used to get GLX info */
+int GHOST_X11_GL_GetAttributes(
+        int *attribs, int attribs_max,
+        int samples, bool is_stereo_visual,
+        bool for_fb_config);
+
 #endif // __GHOST_CONTEXTGLX_H__
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index f4d4825..a0088db 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -52,6 +52,7 @@
 int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent);
 int GHOST_X11_ApplicationIOErrorHandler(Display *display);
 
+
 class GHOST_WindowX11;
 
 /**
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index f716e9b..fe99a8b 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -164,6 +164,8 @@ static XVisualInfo *x11_visualinfo_from_glx(
 {
 	XVisualInfo *visualInfo = NULL;
 	GHOST_TUns16 numOfAASamples = *r_numOfAASamples;
+	GHOST_TUns16 actualSamples;
+
 	/* Set up the minimum attributes that we require and see if
 	 * X can find us a visual matching those requirements. */
 	int glx_major, glx_minor; /* GLX version: major.minor */
@@ -177,68 +179,22 @@ static XVisualInfo *x11_visualinfo_from_glx(
 		return NULL;
 	}
 
-#ifdef GHOST_OPENGL_ALPHA
-	const bool needAlpha = true;
-#else
-	const bool needAlpha = false;
-#endif
-
-#ifdef GHOST_OPENGL_STENCIL
-	const bool needStencil = true;
-#else
-	const bool needStencil = false;
-#endif
+	/* GLX >= 1.4 required for multi-sample */
+	if ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4)) {
+		actualSamples = numOfAASamples;
+	}
+	else {
+		numOfAASamples = 0;
+		actualSamples = 0;
+	}
 
 	/* Find the display with highest samples, starting at level requested */
-	GHOST_TUns16 actualSamples = numOfAASamples;
 	for (;;) {
-		int attribs[20];
-		int iattr = 0;
-
-		if (stereoVisual) {
-			attribs[iattr++] = GLX_STEREO;
-		}
-
-		attribs[iattr++] = GLX_RGBA;
-
-		attribs[iattr++] = GLX_DOUBLEBUFFER;
-
-		attribs[iattr++] = GLX_RED_SIZE;
-		attribs[iattr++] = 1;
-
-		attribs[iattr++] = GLX_BLUE_SIZE;
-		attribs[iattr++] = 1;
-
-		attribs[iattr++] = GLX_GREEN_SIZE;
-		attribs[iattr++] = 1;
-
-		attribs[iattr++] = GLX_DEPTH_SIZE;
-		attribs[iattr++] = 1;
-
-		if (needAlpha) {
-			attribs[iattr++] = GLX_ALPHA_SIZE;
-			attribs[iattr++] = 1;
-		}
-
-		if (needStencil) {
-			attribs[iattr++] = GLX_STENCIL_SIZE;
-			attribs[iattr++] = 1;
-		}
-
-		/* GLX >= 1.4 required for multi-sample */
-		if (actualSamples > 0 && ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4))) {
-			attribs[iattr++] = GLX_SAMPLE_BUFFERS;
-			attribs[iattr++] = 1;
-
-			attribs[iattr++] = GLX_SAMPLES;
-			attribs[iattr++] = actualSamples;
-		}
-
-		attribs[iattr++] = None;
+		int glx_attribs[64];
 
-		GHOST_ASSERT(iattr <= (sizeof(attribs) / sizeof(*attribs)), "Attribute size too small");
+		GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, false);
 
-		visualInfo = glXChooseVisual(display, DefaultScreen(display), attribs);
+		visualInfo = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
 
 		/* Any sample level or even zero, which means oversampling disabled, is good
 		 * but we need a valid visual to continue */




More information about the Bf-blender-cvs mailing list