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
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_ContextGLX.cpp')
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp120
1 files changed, 114 insertions, 6 deletions
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 02b43abec6c..90d810b7986 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;
@@ -87,7 +94,7 @@ GHOST_ContextGLX::~GHOST_ContextGLX()
if (m_context != None) {
if (m_window != 0 && m_context == ::glXGetCurrentContext())
- ::glXMakeCurrent(m_display, m_window, NULL);
+ ::glXMakeCurrent(m_display, None, NULL);
if (m_context != s_sharedContext || s_sharedCount == 1) {
assert(s_sharedCount > 0);
@@ -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;
@@ -257,6 +308,8 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
GHOST_TSuccess success;
if (m_context != NULL) {
+ const unsigned char *version;
+
if (!s_sharedContext)
s_sharedContext = m_context;
@@ -264,13 +317,26 @@ 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);
/* re initialize to get the extensions properly */
initContextGLXEW();
- success = GHOST_kSuccess;
+ version = glGetString(GL_VERSION);
+
+ if (!version || version[0] < '2' || ((version[0] == '2') && (version[2] < '1'))) {
+ fprintf(stderr, "Error! Blender requires OpenGL 2.1 to run. Try updating your drivers.\n");
+ fflush(stderr);
+ /* ugly, but we get crashes unless a whole bunch of systems are patched. */
+ exit(0);
+ }
+ else
+ success = GHOST_kSuccess;
}
else {
/* freeing well clean up the context initialized above */
@@ -409,3 +475,45 @@ int GHOST_X11_GL_GetAttributes(
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 */