diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-11-14 15:43:22 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-11-14 15:43:22 +0300 |
commit | 08974c22e45720bfdc6bba18502175cd3100511f (patch) | |
tree | 627a994ab9888807d2cd6dd57921c451bc2d3dfd | |
parent | 2c3a503731f4d9bbba5fdc0e79a7ae34bd18baf2 (diff) |
Fix X11/GLX failing with multi-sample
Caused by D643, in fact we need to get the visualInfo before creating the window.
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.cpp | 120 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.h | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 10 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 213 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.h | 2 |
5 files changed, 185 insertions, 164 deletions
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 726614c48b1..c4e1346456e 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -54,6 +54,7 @@ GHOST_ContextGLX::GHOST_ContextGLX( GHOST_TUns16 numOfAASamples, Window window, Display *display, + XVisualInfo *visualInfo, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, @@ -61,13 +62,13 @@ GHOST_ContextGLX::GHOST_ContextGLX( int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), m_display(display), + m_visualInfo(visualInfo), m_window(window), m_contextProfileMask(contextProfileMask), m_contextMajorVersion(contextMajorVersion), m_contextMinorVersion(contextMinorVersion), m_contextFlags(contextFlags), m_contextResetNotificationStrategy(contextResetNotificationStrategy), - m_visualInfo(NULL), m_context(None) #ifdef WITH_GLEW_MX , @@ -104,8 +105,6 @@ GHOST_ContextGLX::~GHOST_ContextGLX() delete m_glxewContext; #endif } - - XFree(m_visualInfo); } @@ -145,121 +144,6 @@ void GHOST_ContextGLX::initContextGLXEW() GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() { - /* Set up the minimum attributes that we require and see if - * X can find us a visual matching those requirements. */ - - std::vector<int> attribs; - attribs.reserve(40); - - int glx_major, glx_minor; /* GLX version: major.minor */ - - if (!glXQueryVersion(m_display, &glx_major, &glx_minor)) { - fprintf(stderr, - "%s:%d: X11 glXQueryVersion() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); - - /* exit if this is the first window */ - if (s_sharedContext == NULL) { - fprintf(stderr, "initial window could not find the GLX extension, exit!\n"); - exit(EXIT_FAILURE); - } - - return GHOST_kFailure; - } - -#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 - - /* Find the display with highest samples, starting at level requested */ - int actualSamples = m_numOfAASamples; - for (;;) { - attribs.clear(); - - if (m_stereoVisual) - attribs.push_back(GLX_STEREO); - - attribs.push_back(GLX_RGBA); - - attribs.push_back(GLX_DOUBLEBUFFER); - - attribs.push_back(GLX_RED_SIZE); - attribs.push_back(1); - - attribs.push_back(GLX_BLUE_SIZE); - attribs.push_back(1); - - attribs.push_back(GLX_GREEN_SIZE); - attribs.push_back(1); - - attribs.push_back(GLX_DEPTH_SIZE); - attribs.push_back(1); - - if (needAlpha) { - attribs.push_back(GLX_ALPHA_SIZE); - attribs.push_back(1); - } - - if (needStencil) { - attribs.push_back(GLX_STENCIL_SIZE); - attribs.push_back(1); - } - - /* GLX >= 1.4 required for multi-sample */ - if (actualSamples > 0 && ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4))) { - attribs.push_back(GLX_SAMPLE_BUFFERS); - attribs.push_back(1); - - attribs.push_back(GLX_SAMPLES); - attribs.push_back(actualSamples); - } - - attribs.push_back(None); - - m_visualInfo = glXChooseVisual(m_display, DefaultScreen(m_display), &attribs[0]); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (m_visualInfo != NULL) { - if (actualSamples < m_numOfAASamples) { - fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - m_numOfAASamples, actualSamples); - } - break; - } - - if (actualSamples == 0) { - /* All options exhausted, cannot continue */ - fprintf(stderr, - "%s:%d: X11 glXChooseVisual() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); - - if (s_sharedContext == None) { - fprintf(stderr, "initial window could not find the GLX extension, exit!\n"); - exit(1); - } - - return GHOST_kFailure; - } - else { - --actualSamples; - } - } - - m_numOfAASamples = actualSamples; - #ifdef WITH_X11_XINPUT /* use our own event handlers to avoid exiting blender, * this would happen for eg: diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h index d32adf3338d..9bc17d476fb 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.h +++ b/intern/ghost/intern/GHOST_ContextGLX.h @@ -65,6 +65,7 @@ public: GHOST_TUns16 numOfAASamples, Window window, Display *display, + XVisualInfo *visualInfo, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, @@ -126,6 +127,7 @@ private: void initContextGLXEW(); Display *m_display; + XVisualInfo *m_visualInfo; Window m_window; const int m_contextProfileMask; @@ -134,8 +136,6 @@ private: const int m_contextFlags; const int m_contextResetNotificationStrategy; - XVisualInfo *m_visualInfo; - GLXContext m_context; #ifdef WITH_GLEW_MX diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index e3baebace0d..d4693e99fa5 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -32,6 +32,11 @@ * \ingroup GHOST */ +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include <X11/XKBlib.h> /* allow detectable autorepeate */ +#include <X11/Xutil.h> + #include "GHOST_SystemX11.h" #include "GHOST_WindowX11.h" #include "GHOST_WindowManager.h" @@ -52,11 +57,6 @@ #include "GHOST_Debug.h" -#include <X11/Xatom.h> -#include <X11/keysym.h> -#include <X11/XKBlib.h> /* allow detectable autorepeate */ -#include <X11/Xutil.h> - #ifdef WITH_XF86KEYSYM #include <X11/XF86keysym.h> #endif diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 97f8ae73d2d..ed8e9db85a9 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -29,6 +29,10 @@ * \ingroup GHOST */ +/* For standard X11 cursors */ +#include <X11/cursorfont.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> #include "GHOST_WindowX11.h" #include "GHOST_SystemX11.h" @@ -45,11 +49,6 @@ # include "GHOST_ContextGLX.h" #endif - -/* For standard X11 cursors */ -#include <X11/cursorfont.h> -#include <X11/Xatom.h> - #if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX) # include <strings.h> #endif @@ -153,7 +152,118 @@ static long BLENDER_ICON_48x48x32[] = { 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, 4671303, }; +static XVisualInfo *x11_visualinfo_from_glx( + Display *display, + bool stereoVisual, GHOST_TUns16 *r_numOfAASamples) +{ + XVisualInfo *visualInfo = NULL; + GHOST_TUns16 numOfAASamples = *r_numOfAASamples; + /* Set up the minimum attributes that we require and see if + * X can find us a visual matching those requirements. */ + + std::vector<int> attribs; + attribs.reserve(40); + + int glx_major, glx_minor; /* GLX version: major.minor */ + if (!glXQueryVersion(display, &glx_major, &glx_minor)) { + fprintf(stderr, + "%s:%d: X11 glXQueryVersion() failed, " + "verify working openGL system!\n", + __FILE__, __LINE__); + + 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 + + /* Find the display with highest samples, starting at level requested */ + GHOST_TUns16 actualSamples = numOfAASamples; + for (;;) { + attribs.clear(); + + if (stereoVisual) + attribs.push_back(GLX_STEREO); + + attribs.push_back(GLX_RGBA); + + attribs.push_back(GLX_DOUBLEBUFFER); + + attribs.push_back(GLX_RED_SIZE); + attribs.push_back(1); + + attribs.push_back(GLX_BLUE_SIZE); + attribs.push_back(1); + + attribs.push_back(GLX_GREEN_SIZE); + attribs.push_back(1); + + attribs.push_back(GLX_DEPTH_SIZE); + attribs.push_back(1); + + if (needAlpha) { + attribs.push_back(GLX_ALPHA_SIZE); + attribs.push_back(1); + } + + if (needStencil) { + attribs.push_back(GLX_STENCIL_SIZE); + attribs.push_back(1); + } + + /* GLX >= 1.4 required for multi-sample */ + if (actualSamples > 0 && ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4))) { + attribs.push_back(GLX_SAMPLE_BUFFERS); + attribs.push_back(1); + + attribs.push_back(GLX_SAMPLES); + attribs.push_back(actualSamples); + } + + attribs.push_back(None); + + visualInfo = glXChooseVisual(display, DefaultScreen(display), &attribs[0]); + + /* Any sample level or even zero, which means oversampling disabled, is good + * but we need a valid visual to continue */ + if (visualInfo != NULL) { + if (actualSamples < numOfAASamples) { + fprintf(stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, actualSamples); + } + break; + } + + if (actualSamples == 0) { + /* All options exhausted, cannot continue */ + fprintf(stderr, + "%s:%d: X11 glXChooseVisual() failed, " + "verify working openGL system!\n", + __FILE__, __LINE__); + + return NULL; + } + else { + --actualSamples; + } + } + + *r_numOfAASamples = actualSamples; + + return visualInfo; +} GHOST_WindowX11:: GHOST_WindowX11( @@ -172,6 +282,7 @@ GHOST_WindowX11( const GHOST_TUns16 numOfAASamples) : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples), m_display(display), + m_visualInfo(NULL), m_normal_state(GHOST_kWindowStateNormal), m_system(system), m_valid_setup(false), @@ -180,6 +291,21 @@ GHOST_WindowX11( m_custom_cursor(None), m_visible_cursor(None) { + if (type == GHOST_kDrawingContextTypeOpenGL) { + m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples); + } + else { + XVisualInfo tmp = {0}; + int n; + m_visualInfo = XGetVisualInfo(m_display, 0, &tmp, &n); + } + + /* exit if this is the first window */ + if (m_visualInfo == NULL) { + fprintf(stderr, "initial window could not find the GLX extension, exit!\n"); + exit(EXIT_FAILURE); + } + int natom; unsigned int xattributes_valuemask = 0; @@ -206,21 +332,26 @@ GHOST_WindowX11( xattributes.override_redirect = True; } + xattributes_valuemask |= CWColormap; + xattributes.colormap = XCreateColormap( + m_display, + RootWindow(m_display, m_visualInfo->screen), + m_visualInfo->visual, + AllocNone + ); + /* create the window! */ if (parentWindow == 0) { - m_window = XCreateWindow(m_display, - RootWindow(m_display, DefaultScreen(m_display)), - left, - top, - width, - height, - 0, /* no border. */ - CopyFromParent, - InputOutput, - CopyFromParent, - xattributes_valuemask, - &xattributes - ); + m_window = XCreateWindow( + m_display, + RootWindow(m_display, m_visualInfo->screen), + left, top, width, height, + 0, /* no border. */ + m_visualInfo->depth, + InputOutput, + m_visualInfo->visual, + xattributes_valuemask, + &xattributes); } else { @@ -237,19 +368,16 @@ GHOST_WindowX11( height = h_return; - m_window = XCreateWindow(m_display, - parentWindow, /* reparent against embedder */ - left, - top, - width, - height, - 0, /* no border. */ - CopyFromParent, - InputOutput, - CopyFromParent, - xattributes_valuemask, - &xattributes - ); + m_window = XCreateWindow( + m_display, + parentWindow, /* reparent against embedder */ + left, top, width, height, + 0, /* no border. */ + m_visualInfo->depth, + InputOutput, + m_visualInfo->visual, + xattributes_valuemask, + &xattributes); XSelectInput(m_display, parentWindow, SubstructureNotifyMask); @@ -602,7 +730,7 @@ screenToClient( Window temp; XTranslateCoordinates(m_display, - RootWindow(m_display, DefaultScreen(m_display)), + RootWindow(m_display, m_visualInfo->screen), m_window, inX, inY, &ax, &ay, @@ -625,7 +753,7 @@ clientToScreen( XTranslateCoordinates( m_display, m_window, - RootWindow(m_display, DefaultScreen(m_display)), + RootWindow(m_display, m_visualInfo->screen), inX, inY, &ax, &ay, &temp); @@ -648,7 +776,7 @@ void GHOST_WindowX11::icccmSetState(int state) xev.xclient.format = 32; xev.xclient.message_type = m_system->m_atom.WM_CHANGE_STATE; xev.xclient.data.l[0] = state; - XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)), + XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); } @@ -694,7 +822,7 @@ void GHOST_WindowX11::netwmMaximized(bool set) xev.xclient.data.l[2] = m_system->m_atom._NET_WM_STATE_MAXIMIZED_VERT; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)), + XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } @@ -750,7 +878,7 @@ void GHOST_WindowX11::netwmFullScreen(bool set) xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)), + XSendEvent(m_display, RootWindow(m_display, m_visualInfo->screen), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } @@ -969,7 +1097,7 @@ setOrder( xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - root = RootWindow(m_display, DefaultScreen(m_display)), + root = RootWindow(m_display, m_visualInfo->screen), eventmask = SubstructureRedirectMask | SubstructureNotifyMask; XSendEvent(m_display, root, False, eventmask, &xev); @@ -1068,6 +1196,10 @@ GHOST_WindowX11:: XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime); } + if (m_visualInfo) { + XFree(m_visualInfo); + } + #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING) if (m_xic) { XDestroyIC(m_xic); @@ -1095,6 +1227,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_wantNumOfAASamples, m_window, m_display, + m_visualInfo, GLX_CONTEXT_OPENGL_CORE_PROFILE_BIT, 3, 2, GHOST_OPENGL_GLX_CONTEXT_FLAGS, @@ -1105,6 +1238,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_wantNumOfAASamples, m_window, m_display, + m_visualInfo, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 2, 0, GHOST_OPENGL_GLX_CONTEXT_FLAGS, @@ -1115,6 +1249,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_wantNumOfAASamples, m_window, m_display, + m_visualInfo, 0, // profile bit 0, 0, GHOST_OPENGL_GLX_CONTEXT_FLAGS, @@ -1237,7 +1372,7 @@ getEmptyCursor( /* make a blank cursor */ blank = XCreateBitmapFromData( m_display, - RootWindow(m_display, DefaultScreen(m_display)), + RootWindow(m_display, m_visualInfo->screen), data, 1, 1 ); @@ -1356,7 +1491,7 @@ setWindowCustomCursorShape( int fg_color, int bg_color) { - Colormap colormap = DefaultColormap(m_display, DefaultScreen(m_display)); + Colormap colormap = DefaultColormap(m_display, m_visualInfo->screen); Pixmap bitmap_pix, mask_pix; XColor fg, bg; diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 3255751be93..cd98b394a8d 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -319,6 +319,8 @@ private: Window m_window; Display *m_display; + XVisualInfo *m_visualInfo; + GHOST_TWindowState m_normal_state; /** A pointer to the typed system class. */ |