summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2012-07-07 19:40:15 +0100
committerQt by Nokia <qt-info@nokia.com>2012-07-11 02:48:45 +0200
commit026503152d827d9f42e3424613ecf60aa12b8585 (patch)
treee1bea80deb9b079644841780878e8752847181c0 /src/plugins
parent159b28d97226c9b40e3e47188396a17cee70852e (diff)
XCB: Use glXCreateContextAttribsARB if available
If the GLX ARB extension ARB_create_context is available use the function glXCreateContextAttribsARB to create a context for OpenGL 3 or newer that honours the requested profile and version. If a core profile is requested we also ensure that it is forwards compatible. Also ensure that the stored surface format reflects the requested version. Change-Id: Ie4f77be19bfc400440a2f8c9b3d99240eb430925 Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index cac7018e47..0e7d09eccc 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -60,6 +60,8 @@
QT_BEGIN_NAMESPACE
+typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
: QPlatformOpenGLContext()
, m_screen(screen)
@@ -80,8 +82,48 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, TRUE);
}
- if (m_context)
+ // Resolve entry point for glXCreateContextAttribsARB
+ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
+
+ if (glXCreateContextAttribsARB != 0) {
+
+ QVector<int> contextAttributes;
+ contextAttributes << GLX_CONTEXT_MAJOR_VERSION_ARB << m_format.majorVersion()
+ << GLX_CONTEXT_MINOR_VERSION_ARB << m_format.minorVersion();
+
+ if (m_format.majorVersion() >= 3 || (m_format.majorVersion() == 3 && m_format.minorVersion() > 1)) {
+ if (m_format.profile() == QSurfaceFormat::CoreProfile) {
+ contextAttributes << GLX_CONTEXT_FLAGS_ARB << GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
+ << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ } else {
+ contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ }
+ }
+
+ contextAttributes << None;
+
+ GLXContext context = 0;
+ context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, m_shareContext, true, contextAttributes.data());
+ if (!m_context && m_shareContext) {
+ // re-try without a shared glx context
+ m_shareContext = 0;
+ context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, 0, true, contextAttributes.data());
+ }
+
+ // Set this as our context and destroy the old context
+ if (context) {
+ glXMakeCurrent(DISPLAY_FROM_XCB(screen), 0, 0);
+ glXDestroyContext(DISPLAY_FROM_XCB(screen), m_context);
+ m_context = context;
+ }
+ }
+
+ if (m_context) {
m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context);
+ m_format.setMajorVersion(format.majorVersion());
+ m_format.setMinorVersion(format.minorVersion());
+ }
} else {
XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), screen->screenNumber(), &m_format);
if (!visualInfo)