diff options
Diffstat (limited to 'intern/ghost/intern/GHOST_ContextGLX.cpp')
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.cpp | 108 |
1 files changed, 104 insertions, 4 deletions
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 3cce2236143..0ee8da15dea 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -40,6 +40,13 @@ #include <cstdio> #include <cstring> +/* needed for intel drivers (works w/ mesa-swrast & nvidia) */ +#define USE_GLXEW_INIT_WORKAROUND + +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s); +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end); +#endif #ifdef WITH_GLEW_MX GLXEWContext *glxewContext = NULL; @@ -154,10 +161,54 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif - /* needed so 'GLXEW_ARB_create_context' is valid */ - mxIgnoreNoVersion(1); - initContextGLXEW(); - mxIgnoreNoVersion(0); + + + /* -------------------------------------------------------------------- */ + /* Begin Inline Glew */ + +#ifdef USE_GLXEW_INIT_WORKAROUND + const GLubyte *extStart = (GLubyte *)""; + const GLubyte *extEnd; + if (glXQueryExtension(m_display, NULL, NULL)) { + extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); + if ((extStart == NULL) || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) == NULL || + (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreateContextAttribsARB")) == NULL) + { + extStart = (GLubyte *)""; + } + } + extEnd = extStart + _glewStrLen(extStart); + +#undef GLXEW_ARB_create_context + const bool GLXEW_ARB_create_context = + _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); +#undef GLXEW_ARB_create_context_profile + const bool GLXEW_ARB_create_context_profile = + _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); +#undef GLXEW_ARB_create_context_robustness +const bool GLXEW_ARB_create_context_robustness = + _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); +#ifdef WITH_GLEW_ES +#undef GLXEW_EXT_create_context_es_profile + const bool GLXEW_EXT_create_context_es_profile = + _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); +#undef GLXEW_EXT_create_context_es2_profile + const bool GLXEW_EXT_create_context_es2_profile = + _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* WITH_GLEW_ES */ + + /* End Inline Glew */ + /* -------------------------------------------------------------------- */ +#else + /* important to initialize only glxew (_not_ glew), + * since this breaks w/ Mesa's `swrast`, see: T46431 */ + glxewInit(); +#endif /* USE_GLXEW_INIT_WORKAROUND */ + + if (GLXEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; @@ -246,6 +297,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() if (framebuffer_config) { m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); + XFree(framebuffer_config); } } else { @@ -263,6 +315,10 @@ 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); @@ -404,5 +460,49 @@ int GHOST_X11_GL_GetAttributes( GHOST_ASSERT(i <= attribs_max, "attribute size too small"); + (void)attribs_max; + return i; } + + +/* excuse inlining part of glew */ +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen(const GLubyte *s, GLubyte c) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n) +{ + GLuint i = 0; + if (a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte *p; + GLuint len = _glewStrLen((const GLubyte *)name); + p = start; + while (p < end) { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE; + p += n + 1; + } + return GL_FALSE; +} +#endif /* USE_GLXEW_INIT_WORKAROUND */
\ No newline at end of file |