summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-03-28 08:12:21 +0200
committerLiang Qi <liang.qi@qt.io>2018-03-28 08:12:21 +0200
commit794781e7cff9f7d44af64292796428478ed18663 (patch)
treedae1f8478885d95dac5766ce46d5dd4784ca06f4 /src/plugins/platforms/xcb
parentf69d32b535d456a2441754ef5733c7fb65411d6c (diff)
parente83f1900f657a41036bd16e917527fcb7a52fd2b (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: src/plugins/platforms/cocoa/qnsview.mm src/plugins/platforms/cocoa/qnsview_mouse.mm src/testlib/testlib.pro Change-Id: Ia0ce4243418fe6a485b0f290c67bd433b3b04ff2
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp64
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h2
2 files changed, 58 insertions, 8 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 21024385b0..86ca7afa12 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -86,6 +86,22 @@ typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXC
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#endif
+#ifndef GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB
+#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#endif
+
+#ifndef GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
+#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#endif
+
+#ifndef GLX_LOSE_CONTEXT_ON_RESET_ARB
+#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#endif
+
+#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+#endif
+
static Window createDummyWindow(Display *dpy, XVisualInfo *visualInfo, int screenNumber, Window rootWin)
{
Colormap cmap = XCreateColormap(dpy, rootWin, visualInfo->visual, AllocNone);
@@ -179,6 +195,8 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_isPBufferCurrent(false)
, m_swapInterval(-1)
, m_ownsContext(nativeHandle.isNull())
+ , m_getGraphicsResetStatus(0)
+ , m_lost(false)
{
if (nativeHandle.isNull())
init(screen, share);
@@ -214,6 +232,8 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
const bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile");
+ const bool supportsRobustness = glxExt.contains("GLX_ARB_create_context_robustness");
+ const bool supportsVideoMemoryPurge = glxExt.contains("GLX_NV_robustness_video_memory_purge");
// Use glXCreateContextAttribsARB if available
// Also, GL ES context creation requires GLX_EXT_create_context_es2_profile
@@ -266,6 +286,9 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
int flags = 0;
+ if (supportsRobustness)
+ flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
+
if (m_format.testOption(QSurfaceFormat::DebugContext))
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
@@ -279,14 +302,33 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
contextAttributes << GLX_CONTEXT_PROFILE_MASK_ARB << GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
}
- contextAttributes << None;
+ if (supportsRobustness && supportsVideoMemoryPurge) {
+ QVector<int> contextAttributesWithNvidiaReset = contextAttributes;
+
+ contextAttributesWithNvidiaReset << GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB << GLX_LOSE_CONTEXT_ON_RESET_ARB;
+ contextAttributesWithNvidiaReset << GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV << GL_TRUE;
- m_context = glXCreateContextAttribsARB(m_display, config, m_shareContext, true, contextAttributes.data());
- if (!m_context && m_shareContext) {
- // re-try without a shared glx context
- m_context = glXCreateContextAttribsARB(m_display, config, 0, true, contextAttributes.data());
- if (m_context)
- m_shareContext = 0;
+ contextAttributesWithNvidiaReset << None;
+ m_context = glXCreateContextAttribsARB(m_display, config, m_shareContext, true, contextAttributesWithNvidiaReset.data());
+ if (!m_context && m_shareContext) {
+ // re-try without a shared glx context
+ m_context = glXCreateContextAttribsARB(m_display, config, 0, true, contextAttributesWithNvidiaReset.data());
+ if (m_context)
+ m_shareContext = 0;
+ }
+ }
+
+ if (m_context) {
+ m_getGraphicsResetStatus = reinterpret_cast<GLenum (QOPENGLF_APIENTRYP)()>(getProcAddress("glGetGraphicsResetStatusARB"));
+ } else {
+ contextAttributes << None;
+ m_context = glXCreateContextAttribsARB(m_display, config, m_shareContext, true, contextAttributes.data());
+ if (!m_context && m_shareContext) {
+ // re-try without a shared glx context
+ m_context = glXCreateContextAttribsARB(m_display, config, 0, true, contextAttributes.data());
+ if (m_context)
+ m_shareContext = 0;
+ }
}
}
}
@@ -494,6 +536,12 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
glxDrawable = window->xcb_window();
success = glXMakeCurrent(m_display, glxDrawable, m_context);
+ m_lost = false;
+ if (m_getGraphicsResetStatus && m_getGraphicsResetStatus() != GL_NO_ERROR) {
+ m_lost = true;
+ // Drop the surface. Will recreate on the next makeCurrent.
+ window->invalidateSurface();
+ }
} else if (surfaceClass == QSurface::Offscreen) {
m_isPBufferCurrent = true;
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
@@ -609,7 +657,7 @@ bool QGLXContext::isSharing() const
bool QGLXContext::isValid() const
{
- return m_context != 0;
+ return m_context != 0 && !m_lost;
}
bool QGLXContext::m_queriedDummyContext = false;
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
index f6372582db..be9d3f5dcb 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.h
@@ -89,6 +89,8 @@ private:
bool m_isPBufferCurrent;
int m_swapInterval;
bool m_ownsContext;
+ GLenum (APIENTRY * m_getGraphicsResetStatus)();
+ bool m_lost;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};