Skip to content

Commit ecc04e8

Browse files
mavonarxmvonarx
andauthored
drm: check syncobj timeline support before advertising protocol (#11117)
Prevents crashes on systems where DRM driver lacks syncobj timeline support (e.g., Apple Silicon with Honeykrisp driver). Applications like Zed and WezTerm would crash with 'Timeline failed importing' when trying to use explicit sync. Fixes #8158 #8803 --------- Co-authored-by: mvonarx <matthias.vonarx@sitrox.com>
1 parent c51c6e3 commit ecc04e8

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

src/Compositor.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include <sys/resource.h>
7474
#include <malloc.h>
7575
#include <unistd.h>
76+
#include <xf86drm.h>
7677

7778
using namespace Hyprutils::String;
7879
using namespace Aquamarine;
@@ -167,6 +168,10 @@ void CCompositor::restoreNofile() {
167168
Debug::log(ERR, "Failed restoring NOFILE limits");
168169
}
169170

171+
bool CCompositor::supportsDrmSyncobjTimeline() const {
172+
return m_bDrmSyncobjTimelineSupported;
173+
}
174+
170175
void CCompositor::setMallocThreshold() {
171176
#ifdef M_TRIM_THRESHOLD
172177
// The default is 128 pages,
@@ -354,6 +359,16 @@ void CCompositor::initServer(std::string socketName, int socketFd) {
354359
m_drmFD = m_aqBackend->drmFD();
355360
Debug::log(LOG, "Running on DRMFD: {}", m_drmFD);
356361

362+
if (m_drmFD >= 0) {
363+
uint64_t cap = 0;
364+
int ret = drmGetCap(m_drmFD, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
365+
m_bDrmSyncobjTimelineSupported = (ret == 0 && cap != 0);
366+
Debug::log(LOG, "DRM syncobj timeline support: {}", m_bDrmSyncobjTimelineSupported ? "yes" : "no");
367+
} else {
368+
m_bDrmSyncobjTimelineSupported = false;
369+
Debug::log(LOG, "DRM syncobj timeline support: no (no DRM FD)");
370+
}
371+
357372
if (!socketName.empty() && socketFd != -1) {
358373
fcntl(socketFd, F_SETFD, FD_CLOEXEC);
359374
const auto RETVAL = wl_display_add_socket_fd(m_wlDisplay, socketFd);

src/Compositor.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ class CCompositor {
152152
NColorManagement::SImageDescription getPreferredImageDescription();
153153
bool shouldChangePreferredImageDescription();
154154

155+
bool supportsDrmSyncobjTimeline() const;
155156
std::string m_explicitConfigPath;
156157

157158
private:
@@ -165,6 +166,8 @@ class CCompositor {
165166
void removeLockFile();
166167
void setMallocThreshold();
167168

169+
bool m_bDrmSyncobjTimelineSupported = false;
170+
168171
uint64_t m_hyprlandPID = 0;
169172
wl_event_source* m_critSigSource = nullptr;
170173
rlimit m_originalNofile = {};

src/helpers/sync/SyncTimeline.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#include "SyncTimeline.hpp"
22
#include "../../defines.hpp"
33
#include "../../managers/eventLoop/EventLoopManager.hpp"
4+
#include "../../Compositor.hpp"
45

56
#include <xf86drm.h>
67
#include <sys/eventfd.h>
78
using namespace Hyprutils::OS;
89

910
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
11+
if (!g_pCompositor->supportsDrmSyncobjTimeline())
12+
return nullptr;
13+
1014
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
1115
timeline->m_drmFD = drmFD_;
1216
timeline->m_self = timeline;
@@ -20,6 +24,9 @@ SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
2024
}
2125

2226
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_, CFileDescriptor&& drmSyncobjFD) {
27+
if (!g_pCompositor->supportsDrmSyncobjTimeline())
28+
return nullptr;
29+
2330
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
2431
timeline->m_drmFD = drmFD_;
2532
timeline->m_syncobjFD = std::move(drmSyncobjFD);

src/managers/ProtocolManager.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include "content-type-v1.hpp"
7171

7272
#include <aquamarine/buffer/Buffer.hpp>
73+
#include <xf86drm.h>
7374
#include <aquamarine/backend/Backend.hpp>
7475
#include <hyprutils/memory/UniquePtr.hpp>
7576

@@ -210,8 +211,13 @@ CProtocolManager::CProtocolManager() {
210211
else
211212
lease.reset();
212213

213-
if (g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext && !PROTO::sync)
214-
PROTO::sync = makeUnique<CDRMSyncobjProtocol>(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj");
214+
if (g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext && !PROTO::sync) {
215+
if (g_pCompositor->supportsDrmSyncobjTimeline()) {
216+
PROTO::sync = makeUnique<CDRMSyncobjProtocol>(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj");
217+
Debug::log(LOG, "DRM Syncobj Timeline support detected, enabling explicit sync protocol");
218+
} else
219+
Debug::log(WARN, "DRM Syncobj Timeline not supported, skipping explicit sync protocol");
220+
}
215221
}
216222

217223
if (!g_pHyprOpenGL->getDRMFormats().empty()) {

0 commit comments

Comments
 (0)