diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 53f79012..58292c8a 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -73,6 +73,7 @@ #include #include #include +#include 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); diff --git a/src/Compositor.hpp b/src/Compositor.hpp index b4a0c51c..23d1c365 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -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 = {}; diff --git a/src/helpers/sync/SyncTimeline.cpp b/src/helpers/sync/SyncTimeline.cpp index 1b089caa..614a7c5b 100644 --- a/src/helpers/sync/SyncTimeline.cpp +++ b/src/helpers/sync/SyncTimeline.cpp @@ -1,12 +1,16 @@ #include "SyncTimeline.hpp" #include "../../defines.hpp" #include "../../managers/eventLoop/EventLoopManager.hpp" +#include "../../Compositor.hpp" #include #include using namespace Hyprutils::OS; SP CSyncTimeline::create(int drmFD_) { + if (!g_pCompositor->supportsDrmSyncobjTimeline()) + return nullptr; + auto timeline = SP(new CSyncTimeline); timeline->m_drmFD = drmFD_; timeline->m_self = timeline; @@ -20,6 +24,9 @@ SP CSyncTimeline::create(int drmFD_) { } SP CSyncTimeline::create(int drmFD_, CFileDescriptor&& drmSyncobjFD) { + if (!g_pCompositor->supportsDrmSyncobjTimeline()) + return nullptr; + auto timeline = SP(new CSyncTimeline); timeline->m_drmFD = drmFD_; timeline->m_syncobjFD = std::move(drmSyncobjFD); diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp index eac6dee0..ebd90a45 100644 --- a/src/managers/ProtocolManager.cpp +++ b/src/managers/ProtocolManager.cpp @@ -70,6 +70,7 @@ #include "content-type-v1.hpp" #include +#include #include #include @@ -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(&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(&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()) {