QGLXContext survives screen removal
The screen pointer is usually only used to get the Display, which normally doesn't change anyway. Task-number: QTBUG-39996 Change-Id: Ie35f02fc9330647897a9f081afb8c9ce550eed2a Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
parent
75cf14e413
commit
41826cfbae
@ -162,7 +162,7 @@ static void updateFormatFromContext(QSurfaceFormat &format)
|
|||||||
|
|
||||||
QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
|
QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
|
||||||
: QPlatformOpenGLContext()
|
: QPlatformOpenGLContext()
|
||||||
, m_screen(screen)
|
, m_display(DISPLAY_FROM_XCB(screen))
|
||||||
, m_context(0)
|
, m_context(0)
|
||||||
, m_shareContext(0)
|
, m_shareContext(0)
|
||||||
, m_format(format)
|
, m_format(format)
|
||||||
@ -186,7 +186,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
|||||||
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
|
||||||
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
|
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
|
||||||
|
|
||||||
QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber())).split(' ');
|
QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(m_display, screen->screenNumber())).split(' ');
|
||||||
bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile");
|
bool supportsProfiles = glxExt.contains("GLX_ARB_create_context_profile");
|
||||||
|
|
||||||
// Use glXCreateContextAttribsARB if available
|
// Use glXCreateContextAttribsARB if available
|
||||||
@ -255,10 +255,10 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
|||||||
|
|
||||||
contextAttributes << None;
|
contextAttributes << None;
|
||||||
|
|
||||||
m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, m_shareContext, true, contextAttributes.data());
|
m_context = glXCreateContextAttribsARB(m_display, config, m_shareContext, true, contextAttributes.data());
|
||||||
if (!m_context && m_shareContext) {
|
if (!m_context && m_shareContext) {
|
||||||
// re-try without a shared glx context
|
// re-try without a shared glx context
|
||||||
m_context = glXCreateContextAttribsARB(DISPLAY_FROM_XCB(screen), config, 0, true, contextAttributes.data());
|
m_context = glXCreateContextAttribsARB(m_display, config, 0, true, contextAttributes.data());
|
||||||
if (m_context)
|
if (m_context)
|
||||||
m_shareContext = 0;
|
m_shareContext = 0;
|
||||||
}
|
}
|
||||||
@ -271,10 +271,10 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
|||||||
if (m_format.renderableType() == QSurfaceFormat::OpenGLES)
|
if (m_format.renderableType() == QSurfaceFormat::OpenGLES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, m_shareContext, true);
|
m_context = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, m_shareContext, true);
|
||||||
if (!m_context && m_shareContext) {
|
if (!m_context && m_shareContext) {
|
||||||
// re-try without a shared glx context
|
// re-try without a shared glx context
|
||||||
m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, true);
|
m_context = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, 0, true);
|
||||||
if (m_context)
|
if (m_context)
|
||||||
m_shareContext = 0;
|
m_shareContext = 0;
|
||||||
}
|
}
|
||||||
@ -292,14 +292,14 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Note that m_format gets updated with the used surface format
|
// Note that m_format gets updated with the used surface format
|
||||||
visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(screen), screen->screenNumber(), &m_format);
|
visualInfo = qglx_findVisualInfo(m_display, screen->screenNumber(), &m_format);
|
||||||
if (!visualInfo)
|
if (!visualInfo)
|
||||||
qFatal("Could not initialize GLX");
|
qFatal("Could not initialize GLX");
|
||||||
m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, m_shareContext, true);
|
m_context = glXCreateContext(m_display, visualInfo, m_shareContext, true);
|
||||||
if (!m_context && m_shareContext) {
|
if (!m_context && m_shareContext) {
|
||||||
// re-try without a shared glx context
|
// re-try without a shared glx context
|
||||||
m_shareContext = 0;
|
m_shareContext = 0;
|
||||||
m_context = glXCreateContext(DISPLAY_FROM_XCB(screen), visualInfo, 0, true);
|
m_context = glXCreateContext(m_display, visualInfo, Q_NULLPTR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a temporary window so that we can make the new context current
|
// Create a temporary window so that we can make the new context current
|
||||||
@ -309,20 +309,31 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
|
|||||||
|
|
||||||
// Query the OpenGL version and profile
|
// Query the OpenGL version and profile
|
||||||
if (m_context && window) {
|
if (m_context && window) {
|
||||||
glXMakeCurrent(DISPLAY_FROM_XCB(screen), window, m_context);
|
glXMakeCurrent(m_display, window, m_context);
|
||||||
updateFormatFromContext(m_format);
|
updateFormatFromContext(m_format);
|
||||||
|
|
||||||
// Make our context non-current
|
// Make our context non-current
|
||||||
glXMakeCurrent(DISPLAY_FROM_XCB(screen), 0, 0);
|
glXMakeCurrent(m_display, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy our temporary window
|
// Destroy our temporary window
|
||||||
XDestroyWindow(DISPLAY_FROM_XCB(screen), window);
|
XDestroyWindow(m_display, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
QGLXContext::~QGLXContext()
|
QGLXContext::~QGLXContext()
|
||||||
{
|
{
|
||||||
glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
|
glXDestroyContext(m_display, m_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QXcbScreen *screenForPlatformSurface(QPlatformSurface *surface)
|
||||||
|
{
|
||||||
|
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
|
||||||
|
if (surfaceClass == QSurface::Window) {
|
||||||
|
return static_cast<QXcbScreen *>(static_cast<QXcbWindow *>(surface)->screen());
|
||||||
|
} else if (surfaceClass == QSurface::Offscreen) {
|
||||||
|
return static_cast<QXcbScreen *>(static_cast<QGLXPbuffer *>(surface)->screen());
|
||||||
|
}
|
||||||
|
return Q_NULLPTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
||||||
@ -330,24 +341,24 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
bool success = false;
|
bool success = false;
|
||||||
Q_ASSERT(surface->surface()->supportsOpenGL());
|
Q_ASSERT(surface->surface()->supportsOpenGL());
|
||||||
|
|
||||||
Display *dpy = DISPLAY_FROM_XCB(m_screen);
|
|
||||||
GLXDrawable glxDrawable = 0;
|
GLXDrawable glxDrawable = 0;
|
||||||
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
|
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
|
||||||
if (surfaceClass == QSurface::Window) {
|
if (surfaceClass == QSurface::Window) {
|
||||||
m_isPBufferCurrent = false;
|
m_isPBufferCurrent = false;
|
||||||
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
|
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
|
||||||
glxDrawable = window->xcb_window();
|
glxDrawable = window->xcb_window();
|
||||||
success = glXMakeCurrent(dpy, glxDrawable, m_context);
|
success = glXMakeCurrent(m_display, glxDrawable, m_context);
|
||||||
} else if (surfaceClass == QSurface::Offscreen) {
|
} else if (surfaceClass == QSurface::Offscreen) {
|
||||||
m_isPBufferCurrent = true;
|
m_isPBufferCurrent = true;
|
||||||
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
|
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
|
||||||
glxDrawable = pbuffer->pbuffer();
|
glxDrawable = pbuffer->pbuffer();
|
||||||
success = glXMakeContextCurrent(dpy, glxDrawable, glxDrawable, m_context);
|
success = glXMakeContextCurrent(m_display, glxDrawable, glxDrawable, m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
int interval = surface->format().swapInterval();
|
int interval = surface->format().swapInterval();
|
||||||
if (interval >= 0 && m_swapInterval != interval) {
|
QXcbScreen *screen = screenForPlatformSurface(surface);
|
||||||
|
if (interval >= 0 && m_swapInterval != interval && screen) {
|
||||||
m_swapInterval = interval;
|
m_swapInterval = interval;
|
||||||
typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
|
typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
|
||||||
typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
|
typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
|
||||||
@ -356,15 +367,15 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
static bool resolved = false;
|
static bool resolved = false;
|
||||||
if (!resolved) {
|
if (!resolved) {
|
||||||
resolved = true;
|
resolved = true;
|
||||||
QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(dpy,
|
QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(m_display,
|
||||||
m_screen->screenNumber())).split(' ');
|
screen->screenNumber())).split(' ');
|
||||||
if (glxExt.contains("GLX_EXT_swap_control"))
|
if (glxExt.contains("GLX_EXT_swap_control"))
|
||||||
glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
|
glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
|
||||||
if (glxExt.contains("GLX_MESA_swap_control"))
|
if (glxExt.contains("GLX_MESA_swap_control"))
|
||||||
glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
|
glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
|
||||||
}
|
}
|
||||||
if (glXSwapIntervalEXT)
|
if (glXSwapIntervalEXT)
|
||||||
glXSwapIntervalEXT(dpy, glxDrawable, interval);
|
glXSwapIntervalEXT(m_display, glxDrawable, interval);
|
||||||
else if (glXSwapIntervalMESA)
|
else if (glXSwapIntervalMESA)
|
||||||
glXSwapIntervalMESA(interval);
|
glXSwapIntervalMESA(interval);
|
||||||
}
|
}
|
||||||
@ -376,9 +387,9 @@ bool QGLXContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
void QGLXContext::doneCurrent()
|
void QGLXContext::doneCurrent()
|
||||||
{
|
{
|
||||||
if (m_isPBufferCurrent)
|
if (m_isPBufferCurrent)
|
||||||
glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0, 0);
|
glXMakeContextCurrent(m_display, 0, 0, 0);
|
||||||
else
|
else
|
||||||
glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), 0, 0);
|
glXMakeCurrent(m_display, 0, 0);
|
||||||
m_isPBufferCurrent = false;
|
m_isPBufferCurrent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +400,7 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface)
|
|||||||
glxDrawable = static_cast<QGLXPbuffer *>(surface)->pbuffer();
|
glxDrawable = static_cast<QGLXPbuffer *>(surface)->pbuffer();
|
||||||
else
|
else
|
||||||
glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
|
glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
|
||||||
glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
|
glXSwapBuffers(m_display, glxDrawable);
|
||||||
|
|
||||||
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||||
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(surface);
|
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(surface);
|
||||||
@ -397,7 +408,7 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface)
|
|||||||
// use QueuedConnection to sync the window from the platformWindow's thread
|
// use QueuedConnection to sync the window from the platformWindow's thread
|
||||||
// as QXcbWindow is no QObject, a wrapper slot in QXcbConnection is used.
|
// as QXcbWindow is no QObject, a wrapper slot in QXcbConnection is used.
|
||||||
if (platformWindow->needsSync())
|
if (platformWindow->needsSync())
|
||||||
QMetaObject::invokeMethod(m_screen->connection(), "syncWindow", Qt::QueuedConnection, Q_ARG(QXcbWindow*, platformWindow));
|
QMetaObject::invokeMethod(screenForPlatformSurface(surface)->connection(), "syncWindow", Qt::QueuedConnection, Q_ARG(QXcbWindow*, platformWindow));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +421,7 @@ void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
|
|||||||
if (resolved && !glXGetProcAddressARB)
|
if (resolved && !glXGetProcAddressARB)
|
||||||
return 0;
|
return 0;
|
||||||
if (!glXGetProcAddressARB) {
|
if (!glXGetProcAddressARB) {
|
||||||
QList<QByteArray> glxExt = QByteArray(glXGetClientString(DISPLAY_FROM_XCB(m_screen), GLX_EXTENSIONS)).split(' ');
|
QList<QByteArray> glxExt = QByteArray(glXGetClientString(m_display, GLX_EXTENSIONS)).split(' ');
|
||||||
if (glxExt.contains("GLX_ARB_get_proc_address")) {
|
if (glxExt.contains("GLX_ARB_get_proc_address")) {
|
||||||
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
|
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
|
||||||
void *handle = dlopen(NULL, RTLD_LAZY);
|
void *handle = dlopen(NULL, RTLD_LAZY);
|
||||||
|
@ -76,7 +76,7 @@ public:
|
|||||||
static void queryDummyContext();
|
static void queryDummyContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QXcbScreen *m_screen;
|
Display *m_display;
|
||||||
GLXContext m_context;
|
GLXContext m_context;
|
||||||
GLXContext m_shareContext;
|
GLXContext m_shareContext;
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user