1From 9bc14b7363f4da0ea1f71db3a952a998435a592b Mon Sep 17 00:00:00 2001
2From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
3Date: Thu, 22 Apr 2021 08:42:33 +0200
4Subject: [PATCH 02/17] client: Gracefully handle shutdown and window hiding
5
6When a window is hidden or destroyed, the render thread may already
7be rendering. We need to properly read-lock the surface pointer
8when it is in use and exit when it becomes null.
9
10Note that there is also a potential crash in the Mesa GL driver
11where it keeps a proxy to the wl_surface, so if we delete this
12while we are still rendering, it can crash inside the driver.
13This is not addressed by this patch, and has not been reproduced
14on any other drivers so far.
15
16[ChangeLog][Client] Fixed a crash that could happen when hiding
17or closing windows while Qt Quick was actively rendering on
18a different thread.
19
20Pick-to: 6.0 6.1 5.15
21Fixes: QTBUG-91264
22Fixes: QTBUG-90037
23Task-number: QTBUG-92249
24Change-Id: I029b123b83c58740321e8b90a463ced748d8bcf4
25Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
26Reviewed-by: David Edmundson <davidedmundson@kde.org>
27
28Conflicts:
29	src/client/qwaylandwindow.cpp
30	src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
31
32(cherry picked from commit b19b0fbaf775e8b8eda1e03c265a5393d618c6c0)
33Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
34---
35 src/client/qwaylandwindow.cpp | 15 +++++++++++++--
36 src/client/qwaylandwindow_p.h |  2 +-
37 2 files changed, 14 insertions(+), 3 deletions(-)
38
39diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
40index ceaa4c7..6cbd315 100644
41--- a/src/client/qwaylandwindow.cpp
42+++ b/src/client/qwaylandwindow.cpp
43@@ -414,6 +414,7 @@ void QWaylandWindow::closePopups(QWaylandWindow *parent)
44
45 QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
46 {
47+    QReadLocker lock(&mSurfaceLock);
48     if (mSurface) {
49         if (auto *screen = mSurface->oldestEnteredScreen())
50             return screen;
51@@ -552,6 +553,10 @@ void QWaylandWindow::sendRecursiveExposeEvent()
52
53 void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
54 {
55+    QReadLocker locker(&mSurfaceLock);
56+    if (mSurface == nullptr)
57+        return;
58+
59     if (buffer) {
60         Q_ASSERT(!buffer->committed());
61         handleUpdate();
62@@ -605,6 +610,8 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
63         qCDebug(lcWaylandBackingstore) << "Buffer already committed, ignoring.";
64         return;
65     }
66+
67+    QReadLocker locker(&mSurfaceLock);
68     if (!mSurface)
69         return;
70
71@@ -624,7 +631,9 @@ void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
72
73 void QWaylandWindow::commit()
74 {
75-    mSurface->commit();
76+    QReadLocker locker(&mSurfaceLock);
77+    if (mSurface != nullptr)
78+        mSurface->commit();
79 }
80
81 const wl_callback_listener QWaylandWindow::callbackListener = {
82@@ -723,6 +732,7 @@ QPointF QWaylandWindow::mapFromWlSurface(const QPointF &surfacePosition) const
83
84 wl_surface *QWaylandWindow::wlSurface()
85 {
86+    QReadLocker locker(&mSurfaceLock);
87     return mSurface ? mSurface->object() : nullptr;
88 }
89
90@@ -747,7 +757,8 @@ QWaylandScreen *QWaylandWindow::waylandScreen() const
91
92 void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
93 {
94-    if (mDisplay->compositorVersion() < 2)
95+    QReadLocker locker(&mSurfaceLock);
96+    if (mSurface == nullptr || mDisplay->compositorVersion() < 2)
97         return;
98
99     wl_output_transform transform;
100diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
101index cb9135f..c0a7634 100644
102--- a/src/client/qwaylandwindow_p.h
103+++ b/src/client/qwaylandwindow_p.h
104@@ -288,7 +288,7 @@ private:
105
106     static QWaylandWindow *mMouseGrab;
107
108-    QReadWriteLock mSurfaceLock;
109+    mutable QReadWriteLock mSurfaceLock;
110
111     friend class QWaylandSubSurface;
112 };
113--
1142.20.1
115
116