From 51afc2c2910d6f7c1f2dee9c90f54729d3c3d940 Mon Sep 17 00:00:00 2001 From: fazzi <18248986+fxzzi@users.noreply.github.com> Date: Fri, 18 Apr 2025 20:44:54 +0100 Subject: [PATCH] ctm: enable fade animation on nvidia driver versions 575 and above (#10095) * ctm: enable fade animation on nvidia driver versions 575 and above * format if statement without braces; handle potential throw when checking for nvidia version file --- src/helpers/MiscFunctions.cpp | 35 +++++++++++++++++++++++++++++++++ src/helpers/MiscFunctions.hpp | 1 + src/protocols/CTMControl.cpp | 9 +++++++-- src/render/Renderer.cpp | 37 ++--------------------------------- 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 9e398fd99..88af38c73 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -817,3 +817,38 @@ float stringToPercentage(const std::string& VALUE, const float REL) { else return std::stof(VALUE); } + +// Checks if Nvidia driver major version is at least given version. +// Useful for explicit_sync_kms and ctm_animation as they only work +// past certain driver versions. +bool isNvidiaDriverVersionAtLeast(int threshold) { + static int driverMajor = 0; + static bool once = true; + + if (once) { + once = false; + + std::error_code ec; + if (std::filesystem::exists("/sys/module/nvidia_drm/version", ec) && !ec) { + std::ifstream ifs("/sys/module/nvidia_drm/version"); + if (ifs.good()) { + try { + std::string driverInfo((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); + + size_t firstDot = driverInfo.find('.'); + if (firstDot != std::string::npos) + driverMajor = std::stoi(driverInfo.substr(0, firstDot)); + + Debug::log(LOG, "Parsed NVIDIA major version: {}", driverMajor); + + } catch (std::exception& e) { + driverMajor = 0; // Default to 0 if parsing fails + } + + ifs.close(); + } + } + } + + return driverMajor >= threshold; +} diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index bd2886387..f361313bc 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -39,6 +39,7 @@ bool envEnabled(const std::string& env); Hyprutils::OS::CFileDescriptor allocateSHMFile(size_t len); bool allocateSHMFilePair(size_t size, Hyprutils::OS::CFileDescriptor& rw_fd_ptr, Hyprutils::OS::CFileDescriptor& ro_fd_ptr); float stringToPercentage(const std::string& VALUE, const float REL); +bool isNvidiaDriverVersionAtLeast(int threshold); template [[deprecated("use std::format instead")]] std::string getFormat(std::format_string fmt, Args&&... args) { diff --git a/src/protocols/CTMControl.cpp b/src/protocols/CTMControl.cpp index c3b6862df..7dbe635bb 100644 --- a/src/protocols/CTMControl.cpp +++ b/src/protocols/CTMControl.cpp @@ -6,6 +6,7 @@ #include "../config/ConfigManager.hpp" #include "managers/AnimationManager.hpp" #include "../helpers/Monitor.hpp" +#include "../helpers/MiscFunctions.hpp" CHyprlandCTMControlResource::CHyprlandCTMControlResource(SP resource_) : resource(resource_) { if UNLIKELY (!good()) @@ -109,8 +110,12 @@ void CHyprlandCTMControlProtocol::destroyResource(CHyprlandCTMControlResource* r bool CHyprlandCTMControlProtocol::isCTMAnimationEnabled() { static auto PENABLEANIM = CConfigValue("render:ctm_animation"); - if (*PENABLEANIM == 2) - return !g_pHyprRenderer->isNvidia(); + if (*PENABLEANIM == 2 /* auto */) { + if (!g_pHyprRenderer->isNvidia()) + return true; + // CTM animations are bugged on versions below. + return isNvidiaDriverVersionAtLeast(575); + } return *PENABLEANIM; } diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 8a2d45550..4eee27ff3 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -35,6 +35,7 @@ #include "debug/Log.hpp" #include "../protocols/ColorManagement.hpp" #include "../protocols/types/ContentType.hpp" +#include "../helpers/MiscFunctions.hpp" #include using namespace Hyprutils::Utils; @@ -2349,43 +2350,9 @@ SExplicitSyncSettings CHyprRenderer::getExplicitSyncSettings(SP=560 - // in the case of an error, driverMajor will stay 0 and explicit KMS will be disabled - static int driverMajor = 0; - - static bool once = true; - if (once) { - once = false; - - Debug::log(LOG, "Renderer: checking for explicit KMS support for nvidia"); - - if (std::filesystem::exists("/sys/module/nvidia_drm/version")) { - Debug::log(LOG, "Renderer: Nvidia version file exists"); - - std::ifstream ifs("/sys/module/nvidia_drm/version"); - if (ifs.good()) { - try { - std::string driverInfo((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); - - Debug::log(LOG, "Renderer: Read nvidia version {}", driverInfo); - - CVarList ver(driverInfo, 0, '.', true); - driverMajor = std::stoi(ver[0]); - - Debug::log(LOG, "Renderer: Parsed nvidia major version: {}", driverMajor); - - } catch (std::exception& e) { settings.explicitKMSEnabled = false; } - - ifs.close(); - } - } - } - - settings.explicitKMSEnabled = driverMajor >= 560; + settings.explicitKMSEnabled = isNvidiaDriverVersionAtLeast(560); } } - return settings; }