summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp36
-rw-r--r--src/Compositor.hpp17
-rw-r--r--src/managers/PointerManager.cpp2
-rw-r--r--src/protocols/DRMSyncobj.cpp14
-rw-r--r--src/protocols/LinuxDMABUF.cpp15
-rw-r--r--src/protocols/MesaDRM.cpp24
-rw-r--r--src/render/OpenGL.cpp2
-rw-r--r--src/render/Renderer.cpp14
-rw-r--r--src/render/Renderer.hpp2
9 files changed, 87 insertions, 39 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index a2733042..cbb70e2b 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -169,7 +169,7 @@ void CCompositor::restoreNofile() {
}
bool CCompositor::supportsDrmSyncobjTimeline() const {
- return m_bDrmSyncobjTimelineSupported;
+ return m_drm.syncobjSupport || m_drmRenderNode.syncObjSupport;
}
void CCompositor::setMallocThreshold() {
@@ -356,22 +356,32 @@ void CCompositor::initServer(std::string socketName, int socketFd) {
m_initialized = true;
- m_drmFD = m_aqBackend->drmFD();
- Debug::log(LOG, "Running on DRMFD: {}", m_drmFD);
+ m_drm.fd = m_aqBackend->drmFD();
+ Debug::log(LOG, "Running on DRMFD: {}", m_drm.fd);
+
+ m_drmRenderNode.fd = m_aqBackend->drmRenderNodeFD();
+ Debug::log(LOG, "Using RENDERNODEFD: {}", m_drmRenderNode.fd);
#if defined(__linux__)
- 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)");
- }
+ auto syncObjSupport = [](auto fd) {
+ if (fd < 0)
+ return false;
+
+ uint64_t cap = 0;
+ int ret = drmGetCap(fd, DRM_CAP_SYNCOBJ_TIMELINE, &cap);
+ return ret == 0 && cap != 0;
+ };
+
+ if ((m_drm.syncobjSupport = syncObjSupport(m_drm.fd)))
+ Debug::log(LOG, "DRM DisplayNode syncobj timeline support: {}", m_drm.syncobjSupport ? "yes" : "no");
+
+ if ((m_drmRenderNode.syncObjSupport = syncObjSupport(m_drmRenderNode.fd)))
+ Debug::log(LOG, "DRM RenderNode syncobj timeline support: {}", m_drmRenderNode.syncObjSupport ? "yes" : "no");
+
+ if (!m_drm.syncobjSupport && !m_drmRenderNode.syncObjSupport)
+ Debug::log(LOG, "DRM no syncobj support, disabling explicit sync");
#else
Debug::log(LOG, "DRM syncobj timeline support: no (not linux)");
- m_bDrmSyncobjTimelineSupported = false;
#endif
if (!socketName.empty() && socketFd != -1) {
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 70b18691..eddbe677 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -27,9 +27,18 @@ class CCompositor {
CCompositor(bool onlyConfig = false);
~CCompositor();
- wl_display* m_wlDisplay = nullptr;
- wl_event_loop* m_wlEventLoop = nullptr;
- int m_drmFD = -1;
+ wl_display* m_wlDisplay = nullptr;
+ wl_event_loop* m_wlEventLoop = nullptr;
+ struct {
+ int fd = -1;
+ bool syncobjSupport = false;
+ } m_drm;
+
+ struct {
+ int fd = -1;
+ bool syncObjSupport = false;
+ } m_drmRenderNode;
+
bool m_initialized = false;
SP<Aquamarine::CBackend> m_aqBackend;
@@ -175,8 +184,6 @@ 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/managers/PointerManager.cpp b/src/managers/PointerManager.cpp
index 318ec343..f5635810 100644
--- a/src/managers/PointerManager.cpp
+++ b/src/managers/PointerManager.cpp
@@ -432,7 +432,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
options.length = 2;
options.scanout = true;
options.cursor = true;
- options.multigpu = state->monitor->m_output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_drmFD;
+ options.multigpu = state->monitor->m_output->getBackend()->preferredAllocator()->drmFD() != g_pCompositor->m_drm.fd;
// We do not set the format (unless shm). If it's unset (DRM_FORMAT_INVALID) then the swapchain will pick for us,
// but if it's set, we don't wanna change it.
if (shouldUseCpuBuffer)
diff --git a/src/protocols/DRMSyncobj.cpp b/src/protocols/DRMSyncobj.cpp
index bedec422..0896b904 100644
--- a/src/protocols/DRMSyncobj.cpp
+++ b/src/protocols/DRMSyncobj.cpp
@@ -199,8 +199,18 @@ bool CDRMSyncobjManagerResource::good() {
return m_resource->resource();
}
-CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name) :
- IWaylandProtocol(iface, ver, name), m_drmFD(g_pCompositor->m_drmFD) {}
+CDRMSyncobjProtocol::CDRMSyncobjProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
+ if (g_pCompositor->m_drmRenderNode.syncObjSupport)
+ m_drmFD = g_pCompositor->m_drmRenderNode.fd;
+ else if (g_pCompositor->m_drm.syncobjSupport)
+ m_drmFD = g_pCompositor->m_drm.fd;
+ else {
+ LOGM(ERR, "CDRMSyncobjProtocol: no nodes support explicit sync?");
+ return;
+ }
+
+ LOGM(LOG, "CDRMSyncobjProtocol: using fd {}", m_drmFD);
+}
void CDRMSyncobjProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
const auto& RESOURCE = m_managers.emplace_back(makeUnique<CDRMSyncobjManagerResource>(makeUnique<CWpLinuxDrmSyncobjManagerV1>(client, ver, id)));
diff --git a/src/protocols/LinuxDMABUF.cpp b/src/protocols/LinuxDMABUF.cpp
index 24cf2951..c7de03a2 100644
--- a/src/protocols/LinuxDMABUF.cpp
+++ b/src/protocols/LinuxDMABUF.cpp
@@ -408,7 +408,7 @@ void CLinuxDMABUFResource::sendMods() {
CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
static auto P = g_pHookSystem->hookDynamic("ready", [this](void* self, SCallbackInfo& info, std::any d) {
- int rendererFD = g_pCompositor->m_drmFD;
+ int rendererFD = g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd;
auto dev = devIDFromFD(rendererFD);
if (!dev.has_value()) {
@@ -467,6 +467,19 @@ CLinuxDMABufV1Protocol::CLinuxDMABufV1Protocol(const wl_interface* iface, const
return;
}
+ if (g_pCompositor->m_drmRenderNode.fd >= 0 && rendererFD == g_pCompositor->m_drmRenderNode.fd) {
+ // Already using the compositor's render node, reuse it.
+ m_mainDeviceFD = CFileDescriptor{fcntl(g_pCompositor->m_drmRenderNode.fd, F_DUPFD_CLOEXEC, 0)};
+ drmFreeDevice(&device);
+ if (!m_mainDeviceFD.isValid()) {
+ LOGM(ERR, "failed to open rendernode, disabling linux dmabuf");
+ removeGlobal();
+ return;
+ }
+
+ return; // already using rendernode.
+ }
+
if (device->available_nodes & (1 << DRM_NODE_RENDER)) {
const char* name = device->nodes[DRM_NODE_RENDER];
m_mainDeviceFD = CFileDescriptor{open(name, O_RDWR | O_CLOEXEC)};
diff --git a/src/protocols/MesaDRM.cpp b/src/protocols/MesaDRM.cpp
index 45ee24c5..789f90b6 100644
--- a/src/protocols/MesaDRM.cpp
+++ b/src/protocols/MesaDRM.cpp
@@ -113,28 +113,26 @@ bool CMesaDRMResource::good() {
CMesaDRMProtocol::CMesaDRMProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
drmDevice* dev = nullptr;
- int drmFD = g_pCompositor->m_drmFD;
+ int drmFD = g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd;
+
if (drmGetDevice2(drmFD, 0, &dev) != 0) {
- LOGM(ERR, "Failed to get device, disabling MesaDRM");
+ LOGM(ERR, "Failed to get device from fd {}, disabling MesaDRM", drmFD);
removeGlobal();
return;
}
- if (dev->available_nodes & (1 << DRM_NODE_RENDER)) {
+ if (dev->available_nodes & (1 << DRM_NODE_RENDER) && dev->nodes[DRM_NODE_RENDER]) {
m_nodeName = dev->nodes[DRM_NODE_RENDER];
- } else {
- ASSERT(dev->available_nodes & (1 << DRM_NODE_PRIMARY));
-
- if (!dev->nodes[DRM_NODE_PRIMARY]) {
- LOGM(ERR, "No DRM render node available, both render and primary are null, disabling MesaDRM");
- drmFreeDevice(&dev);
- removeGlobal();
- return;
- }
-
+ } else if (dev->available_nodes & (1 << DRM_NODE_PRIMARY) && dev->nodes[DRM_NODE_PRIMARY]) {
LOGM(WARN, "No DRM render node, falling back to primary {}", dev->nodes[DRM_NODE_PRIMARY]);
m_nodeName = dev->nodes[DRM_NODE_PRIMARY];
+ } else {
+ LOGM(ERR, "No usable DRM node (render or primary) found, disabling MesaDRM");
+ drmFreeDevice(&dev);
+ removeGlobal();
+ return;
}
+
drmFreeDevice(&dev);
}
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 27abe81f..f4599a84 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -254,7 +254,7 @@ EGLDeviceEXT CHyprOpenGLImpl::eglDeviceFromDRMFD(int drmFD) {
return EGL_NO_DEVICE_EXT;
}
-CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmFD) {
+CHyprOpenGLImpl::CHyprOpenGLImpl() : m_drmFD(g_pCompositor->m_drmRenderNode.fd >= 0 ? g_pCompositor->m_drmRenderNode.fd : g_pCompositor->m_drm.fd) {
const std::string EGLEXTENSIONS = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
Debug::log(LOG, "Supported EGL global extensions: ({}) {}", std::ranges::count(EGLEXTENSIONS, ' '), EGLEXTENSIONS);
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index beeb0f5a..cf8ed0ba 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -69,6 +69,8 @@ CHyprRenderer::CHyprRenderer() {
m_nvidia = true;
else if (name.contains("i915"))
m_intel = true;
+ else if (name.contains("softpipe") || name.contains("Software Rasterizer") || name.contains("llvmpipe"))
+ m_software = true;
Debug::log(LOG, "DRM driver information: {} v{}.{}.{} from {} description {}", name, DRMV->version_major, DRMV->version_minor, DRMV->version_patchlevel,
std::string{DRMV->date, DRMV->date_len}, std::string{DRMV->desc, DRMV->desc_len});
@@ -79,7 +81,7 @@ CHyprRenderer::CHyprRenderer() {
} else {
Debug::log(LOG, "Aq backend has no session, omitting full DRM node checks");
- const auto DRMV = drmGetVersion(g_pCompositor->m_drmFD);
+ const auto DRMV = drmGetVersion(g_pCompositor->m_drm.fd);
if (DRMV) {
std::string name = std::string{DRMV->name, DRMV->name_len};
@@ -89,6 +91,8 @@ CHyprRenderer::CHyprRenderer() {
m_nvidia = true;
else if (name.contains("i915"))
m_intel = true;
+ else if (name.contains("softpipe") || name.contains("Software Rasterizer") || name.contains("llvmpipe"))
+ m_software = true;
Debug::log(LOG, "Primary DRM driver information: {} v{}.{}.{} from {} description {}", name, DRMV->version_major, DRMV->version_minor, DRMV->version_patchlevel,
std::string{DRMV->date, DRMV->date_len}, std::string{DRMV->desc, DRMV->desc_len});
@@ -2234,8 +2238,8 @@ void CHyprRenderer::endRender(const std::function<void()>& renderingDoneCallback
if (!g_pHyprOpenGL->explicitSyncSupported()) {
Debug::log(TRACE, "renderer: Explicit sync unsupported, falling back to implicit in endRender");
- // nvidia doesn't have implicit sync, so we have to explicitly wait here
- if (isNvidia() && *PNVIDIAANTIFLICKER)
+ // nvidia doesn't have implicit sync, so we have to explicitly wait here, llvmpipe and other software renderer seems to bug out aswell.
+ if ((isNvidia() && *PNVIDIAANTIFLICKER) || isSoftware())
glFinish();
else
glFlush(); // mark an implicit sync point
@@ -2295,6 +2299,10 @@ bool CHyprRenderer::isIntel() {
return m_intel;
}
+bool CHyprRenderer::isSoftware() {
+ return m_software;
+}
+
bool CHyprRenderer::isMgpu() {
return m_mgpu;
}
diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp
index a986b63b..b1e514f3 100644
--- a/src/render/Renderer.hpp
+++ b/src/render/Renderer.hpp
@@ -75,6 +75,7 @@ class CHyprRenderer {
SP<CRenderbuffer> getCurrentRBO();
bool isNvidia();
bool isIntel();
+ bool isSoftware();
bool isMgpu();
void makeEGLCurrent();
void unsetEGL();
@@ -143,6 +144,7 @@ class CHyprRenderer {
eRenderMode m_renderMode = RENDER_MODE_NORMAL;
bool m_nvidia = false;
bool m_intel = false;
+ bool m_software = false;
bool m_mgpu = false;
struct {