summaryrefslogtreecommitdiff
path: root/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2021-11-10 13:18:30 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2021-12-21 11:21:25 +0100
commitdff579147b07cd15888a47c303e36684e9930f9f (patch)
tree995c5d29f84e3eb8da9231d865985593464f727c /src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
parent719a55be13bdadfa659a732755f280e276a894bd (diff)
downloadqtwayland-dff579147b07cd15888a47c303e36684e9930f9f.tar.gz
client: Fix crash on shutdown on Mesa driver
On Wayland, then the mesa driver is in use, calling eglDestroySurface() while OpenGL commands are being executed may crash. While this means the driver does not operate by the specs in this case, the driver is so popular that it makes sense to work around it. To work around this, we read-lock the surface while rendering and wait for a write-lock before we destroy the EGL surface. [ChangeLog][QtWaylandClient] Fixed a crash on shutdown that could happen with some graphics-heavy applications when running on Mesa drivers. Pick-to: 6.3 Fixes: QTBUG-92249 Change-Id: I8b8461066cc9f948dc44ddeeddaa6e7d92b76f04 Reviewed-by: Liang Qi <liang.qi@qt.io>
Diffstat (limited to 'src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp')
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
index 65ec22f1..e9b290a7 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
@@ -300,6 +300,18 @@ QWaylandGLContext::~QWaylandGLContext()
eglDestroyContext(eglDisplay(), m_decorationsContext);
}
+void QWaylandGLContext::beginFrame()
+{
+ Q_ASSERT(m_currentWindow != nullptr);
+ m_currentWindow->beginFrame();
+}
+
+void QWaylandGLContext::endFrame()
+{
+ Q_ASSERT(m_currentWindow != nullptr);
+ m_currentWindow->endFrame();
+}
+
bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
{
// in QWaylandGLContext() we called eglBindAPI with the correct value. However,
@@ -311,10 +323,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
eglBindAPI(m_api);
}
- QWaylandEglWindow *window = static_cast<QWaylandEglWindow *>(surface);
- EGLSurface eglSurface = window->eglSurface();
+ m_currentWindow = static_cast<QWaylandEglWindow *>(surface);
+ EGLSurface eglSurface = m_currentWindow->eglSurface();
- if (!window->needToUpdateContentFBO() && (eglSurface != EGL_NO_SURFACE)) {
+ if (!m_currentWindow->needToUpdateContentFBO() && (eglSurface != EGL_NO_SURFACE)) {
if (!eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext())) {
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
return false;
@@ -322,26 +334,26 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
return true;
}
- if (window->isExposed())
- window->setCanResize(false);
- if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
- window->createDecoration();
+ if (m_currentWindow->isExposed())
+ m_currentWindow->setCanResize(false);
+ if (m_decorationsContext != EGL_NO_CONTEXT && !m_currentWindow->decoration())
+ m_currentWindow->createDecoration();
if (eglSurface == EGL_NO_SURFACE) {
- window->updateSurface(true);
- eglSurface = window->eglSurface();
+ m_currentWindow->updateSurface(true);
+ eglSurface = m_currentWindow->eglSurface();
}
if (!eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext())) {
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
- window->setCanResize(true);
+ m_currentWindow->setCanResize(true);
return false;
}
//### setCurrentContext will be called in QOpenGLContext::makeCurrent after this function
// returns, but that's too late, as we need a current context in order to bind the content FBO.
QOpenGLContextPrivate::setCurrentContext(context());
- window->bindContentFBO();
+ m_currentWindow->bindContentFBO();
return true;
}