mirror of
https://github.com/hyprwm/Hyprland
synced 2026-01-06 18:10:09 +01:00
animation: improve animations on multi refresh rate monitors (#12418)
This commit is contained in:
parent
56904edbd2
commit
2b0fd417d3
3 changed files with 34 additions and 22 deletions
|
|
@ -18,16 +18,7 @@
|
|||
|
||||
static int wlTick(SP<CEventLoopTimer> self, void* data) {
|
||||
if (g_pAnimationManager)
|
||||
g_pAnimationManager->onTicked();
|
||||
|
||||
if (g_pCompositor->m_sessionActive && g_pAnimationManager && g_pHookSystem && !g_pCompositor->m_unsafeState &&
|
||||
std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; })) {
|
||||
g_pAnimationManager->tick();
|
||||
EMIT_HOOK_EVENT("tick", nullptr);
|
||||
}
|
||||
|
||||
if (g_pAnimationManager && g_pAnimationManager->shouldTickForNext())
|
||||
g_pAnimationManager->scheduleTick();
|
||||
g_pAnimationManager->frameTick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -249,26 +240,40 @@ void CHyprAnimationManager::tick() {
|
|||
tickDone();
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::frameTick() {
|
||||
onTicked();
|
||||
|
||||
if (!shouldTickForNext())
|
||||
return;
|
||||
|
||||
if (!g_pCompositor->m_sessionActive || !g_pHookSystem || g_pCompositor->m_unsafeState ||
|
||||
!std::ranges::any_of(g_pCompositor->m_monitors, [](const auto& mon) { return mon->m_enabled && mon->m_output; }))
|
||||
return;
|
||||
|
||||
if (!m_lastTickValid || m_lastTickTimer.getMillis() >= 1.0f) {
|
||||
m_lastTickTimer.reset();
|
||||
m_lastTickValid = true;
|
||||
|
||||
tick();
|
||||
EMIT_HOOK_EVENT("tick", nullptr);
|
||||
}
|
||||
|
||||
if (shouldTickForNext())
|
||||
scheduleTick();
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::scheduleTick() {
|
||||
if (m_tickScheduled)
|
||||
return;
|
||||
|
||||
m_tickScheduled = true;
|
||||
|
||||
const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor;
|
||||
|
||||
if (!PMOSTHZ) {
|
||||
m_animationTimer->updateTimeout(std::chrono::milliseconds(16));
|
||||
if (!m_animationTimer || !g_pEventLoopManager) {
|
||||
m_tickScheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate);
|
||||
|
||||
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(Time::steadyNow() - PMOSTHZ->m_lastPresentationTimer.chrono()).count() / 1000.F;
|
||||
|
||||
const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it
|
||||
|
||||
m_animationTimer->updateTimeout(std::chrono::milliseconds(sc<int>(std::floor(TOPRES))));
|
||||
m_animationTimer->updateTimeout(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::onTicked() {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../../defines.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
#include "../../desktop/DesktopTypes.hpp"
|
||||
#include "../../helpers/time/Timer.hpp"
|
||||
#include "../eventLoop/EventLoopTimer.hpp"
|
||||
|
||||
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
|
|
@ -13,6 +14,7 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
|||
CHyprAnimationManager();
|
||||
|
||||
void tick();
|
||||
void frameTick();
|
||||
virtual void scheduleTick();
|
||||
virtual void onTicked();
|
||||
|
||||
|
|
@ -52,7 +54,9 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
|||
float m_lastTickTimeMs;
|
||||
|
||||
private:
|
||||
bool m_tickScheduled = false;
|
||||
bool m_tickScheduled = false;
|
||||
bool m_lastTickValid = false;
|
||||
CTimer m_lastTickTimer;
|
||||
};
|
||||
|
||||
inline UP<CHyprAnimationManager> g_pAnimationManager;
|
||||
|
|
|
|||
|
|
@ -1247,6 +1247,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
|
|||
if (!g_pCompositor->m_sessionActive)
|
||||
return;
|
||||
|
||||
if (g_pAnimationManager)
|
||||
g_pAnimationManager->frameTick();
|
||||
|
||||
if (pMonitor->m_id == m_mostHzMonitor->m_id ||
|
||||
*PVFR == 1) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue