110 lines
3.7 KiB
Diff
110 lines
3.7 KiB
Diff
From 1012f1d4b5753ad63da3cca1226fb034e297ae6d Mon Sep 17 00:00:00 2001
|
|
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
Date: Tue, 8 Nov 2022 16:10:18 +0200
|
|
Subject: [PATCH 41/55] Client: Ensure that wl_surface lives as long as qtquick
|
|
render thread needs it
|
|
|
|
wl_surface can be destroyed while qtquick render thread still uses it.
|
|
That can end up in eglSwapBuffers() using defunct wl_surface, which will
|
|
eventually lead to a crash due to the compositor posting an error.
|
|
|
|
This is partially cherry-pick of dff579147b07cd15888a47c303e36684e9930f9f
|
|
|
|
Change-Id: I044f40dd64e6672027a833379b57ccd9973d8305
|
|
---
|
|
src/client/qwaylandwindow.cpp | 13 ++++++++++++-
|
|
src/client/qwaylandwindow_p.h | 3 +++
|
|
.../client/wayland-egl/qwaylandglcontext.cpp | 6 +++++-
|
|
3 files changed, 20 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
|
|
index 4ddf9fbe..1f2d56b5 100644
|
|
--- a/src/client/qwaylandwindow.cpp
|
|
+++ b/src/client/qwaylandwindow.cpp
|
|
@@ -76,6 +76,7 @@ QWaylandWindow *QWaylandWindow::mMouseGrab = nullptr;
|
|
QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
|
|
: QPlatformWindow(window)
|
|
, mDisplay(display)
|
|
+ , mSurfaceLock(QReadWriteLock::Recursive)
|
|
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
|
|
{
|
|
{
|
|
@@ -237,6 +238,16 @@ bool QWaylandWindow::shouldCreateSubSurface() const
|
|
return QPlatformWindow::parent() != nullptr;
|
|
}
|
|
|
|
+void QWaylandWindow::beginFrame()
|
|
+{
|
|
+ mSurfaceLock.lockForRead();
|
|
+}
|
|
+
|
|
+void QWaylandWindow::endFrame()
|
|
+{
|
|
+ mSurfaceLock.unlock();
|
|
+}
|
|
+
|
|
void QWaylandWindow::reset()
|
|
{
|
|
closeChildPopups();
|
|
@@ -245,10 +256,10 @@ void QWaylandWindow::reset()
|
|
delete mSubSurfaceWindow;
|
|
mSubSurfaceWindow = nullptr;
|
|
|
|
- invalidateSurface();
|
|
if (mSurface) {
|
|
emit wlSurfaceDestroyed();
|
|
QWriteLocker lock(&mSurfaceLock);
|
|
+ invalidateSurface();
|
|
mSurface.reset();
|
|
}
|
|
|
|
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
|
|
index ea3d1995..e18609d9 100644
|
|
--- a/src/client/qwaylandwindow_p.h
|
|
+++ b/src/client/qwaylandwindow_p.h
|
|
@@ -207,6 +207,9 @@ public:
|
|
void handleUpdate();
|
|
void deliverUpdateRequest() override;
|
|
|
|
+ void beginFrame();
|
|
+ void endFrame();
|
|
+
|
|
void addChildPopup(QWaylandWindow* child);
|
|
void removeChildPopup(QWaylandWindow* child);
|
|
void closeChildPopups();
|
|
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
index c1f45fa6..5d6fb2bf 100644
|
|
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
|
|
@@ -432,8 +432,10 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
|
return true;
|
|
}
|
|
|
|
- if (window->isExposed())
|
|
+ if (window->isExposed()) {
|
|
+ window->beginFrame();
|
|
window->setCanResize(false);
|
|
+ }
|
|
if (m_decorationsContext != EGL_NO_CONTEXT && !window->decoration())
|
|
window->createDecoration();
|
|
|
|
@@ -449,6 +451,7 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
|
|
if (!eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
|
|
qWarning("QWaylandGLContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
|
|
window->setCanResize(true);
|
|
+ window->endFrame();
|
|
return false;
|
|
}
|
|
|
|
@@ -502,6 +505,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
|
|
eglSwapBuffers(m_eglDisplay, eglSurface);
|
|
|
|
window->setCanResize(true);
|
|
+ window->endFrame();
|
|
}
|
|
|
|
GLuint QWaylandGLContext::defaultFramebufferObject(QPlatformSurface *surface) const
|
|
--
|
|
2.40.0
|
|
|