summaryrefslogtreecommitdiff
path: root/dev-qt/qtwayland/files/qtwayland-5.15.2-fixup-mutexes.patch
blob: b861cebe60ac637e02e011428021ce5619d75bba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
From bf4335b1ea9b179076cbd7a1c2e8cfa9538b1dc1 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Thu, 3 Feb 2022 14:27:08 +0000
Subject: [PATCH] Fix up mutexes for frame callbacks

Everything related to frame callback timings is used by potentially 3
threads. Access needs guarding.

Change-Id: I9f22390c175d9f2f63d31b1ebf0cdc0b830be937
---
 src/client/qwaylandwindow.cpp | 14 +++++++++-----
 src/client/qwaylandwindow_p.h | 10 +++++++---
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 7aee362a..72e0e601 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -256,8 +256,12 @@ void QWaylandWindow::reset()
         mFrameCallback = nullptr;
     }
 
-    mFrameCallbackElapsedTimer.invalidate();
-    mWaitingForFrameCallback = false;
+    {
+        QMutexLocker locker(&mFrameSyncMutex);
+        mFrameCallbackElapsedTimer.invalidate();
+        mWaitingForFrameCallback = false;
+    }
+
     mFrameCallbackTimedOut = false;
 
     mMask = QRegion();
@@ -1142,6 +1146,7 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa
 
 void QWaylandWindow::timerEvent(QTimerEvent *event)
 {
+    QMutexLocker locker(&mFrameSyncMutex);
     if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
         return;
 
@@ -1200,15 +1205,14 @@ void QWaylandWindow::handleUpdate()
 {
     qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
 
-    if (mWaitingForFrameCallback)
-        return;
-
     // TODO: Should sync subsurfaces avoid requesting frame callbacks?
     QReadLocker lock(&mSurfaceLock);
     if (!mSurface)
         return;
 
     QMutexLocker locker(&mFrameSyncMutex);
+    if (mWaitingForFrameCallback)
+        return;
 
     struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface *>(wl_proxy_create_wrapper(mSurface->object()));
     wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface), mDisplay->frameEventQueue());
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 3ff68ccb..025d7917 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -226,13 +226,17 @@ protected:
     Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
 
     WId mWindowId;
+
+    // The following are used by the main thread the render thread and the event frame thread
+    // Access should be guarded by mFrameSyncMutex
+    QMutex mFrameSyncMutex;
+    QWaitCondition mFrameSyncWait;
     bool mWaitingForFrameCallback = false;
-    bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
     int mFrameCallbackCheckIntervalTimerId = -1;
     QElapsedTimer mFrameCallbackElapsedTimer;
+
+    bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
     struct ::wl_callback *mFrameCallback = nullptr;
-    QMutex mFrameSyncMutex;
-    QWaitCondition mFrameSyncWait;
 
     // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
     bool mWaitingForUpdate = false;
-- 
GitLab