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
path: root/intern
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-07-20 06:27:46 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-07-20 06:32:20 +0300
commit86e6d6695e815746e877f9a4234f6805d5a4c155 (patch)
tree531bbcc191a5d5a803deee90b1d27a8e6ae76b4d /intern
parentb36872446418f73a0d494fe193a38af10d14ba2d (diff)
GHOST/X11: Support GLX-Context flags
GHOST_ContextGLX was incomplete, ignoring profile-mask and profile-flags.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp186
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h7
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h1
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp70
4 files changed, 201 insertions, 63 deletions
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index c4e1346456e..487e4939f5d 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 04fe58a0e82..8c2231a0b01 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 f4d4825a12a..a0088dbe8f0 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 f716e9b84f6..fe99a8bee1e 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 */