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