mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-25 17:21:54 -07:00
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>
This commit is contained in:
@@ -73,6 +73,7 @@
|
||||
#include <sys/resource.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Aquamarine;
|
||||
@@ -167,6 +168,10 @@ void CCompositor::restoreNofile() {
|
||||
Debug::log(ERR, "Failed restoring NOFILE limits");
|
||||
}
|
||||
|
||||
bool CCompositor::supportsDrmSyncobjTimeline() const {
|
||||
return m_bDrmSyncobjTimelineSupported;
|
||||
}
|
||||
|
||||
void CCompositor::setMallocThreshold() {
|
||||
#ifdef M_TRIM_THRESHOLD
|
||||
// The default is 128 pages,
|
||||
@@ -354,6 +359,16 @@ void CCompositor::initServer(std::string socketName, int socketFd) {
|
||||
m_drmFD = m_aqBackend->drmFD();
|
||||
Debug::log(LOG, "Running on DRMFD: {}", m_drmFD);
|
||||
|
||||
if (m_drmFD >= 0) {
|
||||
uint64_t cap = 0;
|
||||
int ret = drmGetCap(m_drmFD, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
|
||||
m_bDrmSyncobjTimelineSupported = (ret == 0 && cap != 0);
|
||||
Debug::log(LOG, "DRM syncobj timeline support: {}", m_bDrmSyncobjTimelineSupported ? "yes" : "no");
|
||||
} else {
|
||||
m_bDrmSyncobjTimelineSupported = false;
|
||||
Debug::log(LOG, "DRM syncobj timeline support: no (no DRM FD)");
|
||||
}
|
||||
|
||||
if (!socketName.empty() && socketFd != -1) {
|
||||
fcntl(socketFd, F_SETFD, FD_CLOEXEC);
|
||||
const auto RETVAL = wl_display_add_socket_fd(m_wlDisplay, socketFd);
|
||||
|
@@ -152,6 +152,7 @@ class CCompositor {
|
||||
NColorManagement::SImageDescription getPreferredImageDescription();
|
||||
bool shouldChangePreferredImageDescription();
|
||||
|
||||
bool supportsDrmSyncobjTimeline() const;
|
||||
std::string m_explicitConfigPath;
|
||||
|
||||
private:
|
||||
@@ -165,6 +166,8 @@ class CCompositor {
|
||||
void removeLockFile();
|
||||
void setMallocThreshold();
|
||||
|
||||
bool m_bDrmSyncobjTimelineSupported = false;
|
||||
|
||||
uint64_t m_hyprlandPID = 0;
|
||||
wl_event_source* m_critSigSource = nullptr;
|
||||
rlimit m_originalNofile = {};
|
||||
|
@@ -1,12 +1,16 @@
|
||||
#include "SyncTimeline.hpp"
|
||||
#include "../../defines.hpp"
|
||||
#include "../../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <sys/eventfd.h>
|
||||
using namespace Hyprutils::OS;
|
||||
|
||||
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
|
||||
if (!g_pCompositor->supportsDrmSyncobjTimeline())
|
||||
return nullptr;
|
||||
|
||||
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
|
||||
timeline->m_drmFD = drmFD_;
|
||||
timeline->m_self = timeline;
|
||||
@@ -20,6 +24,9 @@ SP<CSyncTimeline> CSyncTimeline::create(int drmFD_) {
|
||||
}
|
||||
|
||||
SP<CSyncTimeline> CSyncTimeline::create(int drmFD_, CFileDescriptor&& drmSyncobjFD) {
|
||||
if (!g_pCompositor->supportsDrmSyncobjTimeline())
|
||||
return nullptr;
|
||||
|
||||
auto timeline = SP<CSyncTimeline>(new CSyncTimeline);
|
||||
timeline->m_drmFD = drmFD_;
|
||||
timeline->m_syncobjFD = std::move(drmSyncobjFD);
|
||||
|
@@ -70,6 +70,7 @@
|
||||
#include "content-type-v1.hpp"
|
||||
|
||||
#include <aquamarine/buffer/Buffer.hpp>
|
||||
#include <xf86drm.h>
|
||||
#include <aquamarine/backend/Backend.hpp>
|
||||
#include <hyprutils/memory/UniquePtr.hpp>
|
||||
|
||||
@@ -210,8 +211,13 @@ CProtocolManager::CProtocolManager() {
|
||||
else
|
||||
lease.reset();
|
||||
|
||||
if (g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext && !PROTO::sync)
|
||||
PROTO::sync = makeUnique<CDRMSyncobjProtocol>(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj");
|
||||
if (g_pHyprOpenGL->m_exts.EGL_ANDROID_native_fence_sync_ext && !PROTO::sync) {
|
||||
if (g_pCompositor->supportsDrmSyncobjTimeline()) {
|
||||
PROTO::sync = makeUnique<CDRMSyncobjProtocol>(&wp_linux_drm_syncobj_manager_v1_interface, 1, "DRMSyncobj");
|
||||
Debug::log(LOG, "DRM Syncobj Timeline support detected, enabling explicit sync protocol");
|
||||
} else
|
||||
Debug::log(WARN, "DRM Syncobj Timeline not supported, skipping explicit sync protocol");
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_pHyprOpenGL->getDRMFormats().empty()) {
|
||||
|
Reference in New Issue
Block a user