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) {
|
static int wlTick(SP<CEventLoopTimer> self, void* data) {
|
||||||
if (g_pAnimationManager)
|
if (g_pAnimationManager)
|
||||||
g_pAnimationManager->onTicked();
|
g_pAnimationManager->frameTick();
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -249,26 +240,40 @@ void CHyprAnimationManager::tick() {
|
||||||
tickDone();
|
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() {
|
void CHyprAnimationManager::scheduleTick() {
|
||||||
if (m_tickScheduled)
|
if (m_tickScheduled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_tickScheduled = true;
|
m_tickScheduled = true;
|
||||||
|
|
||||||
const auto PMOSTHZ = g_pHyprRenderer->m_mostHzMonitor;
|
if (!m_animationTimer || !g_pEventLoopManager) {
|
||||||
|
m_tickScheduled = false;
|
||||||
if (!PMOSTHZ) {
|
|
||||||
m_animationTimer->updateTimeout(std::chrono::milliseconds(16));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->m_refreshRate);
|
m_animationTimer->updateTimeout(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
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))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprAnimationManager::onTicked() {
|
void CHyprAnimationManager::onTicked() {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../../defines.hpp"
|
#include "../../defines.hpp"
|
||||||
#include "../../helpers/AnimatedVariable.hpp"
|
#include "../../helpers/AnimatedVariable.hpp"
|
||||||
#include "../../desktop/DesktopTypes.hpp"
|
#include "../../desktop/DesktopTypes.hpp"
|
||||||
|
#include "../../helpers/time/Timer.hpp"
|
||||||
#include "../eventLoop/EventLoopTimer.hpp"
|
#include "../eventLoop/EventLoopTimer.hpp"
|
||||||
|
|
||||||
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||||
|
|
@ -13,6 +14,7 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||||
CHyprAnimationManager();
|
CHyprAnimationManager();
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
|
void frameTick();
|
||||||
virtual void scheduleTick();
|
virtual void scheduleTick();
|
||||||
virtual void onTicked();
|
virtual void onTicked();
|
||||||
|
|
||||||
|
|
@ -53,6 +55,8 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_tickScheduled = false;
|
bool m_tickScheduled = false;
|
||||||
|
bool m_lastTickValid = false;
|
||||||
|
CTimer m_lastTickTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline UP<CHyprAnimationManager> g_pAnimationManager;
|
inline UP<CHyprAnimationManager> g_pAnimationManager;
|
||||||
|
|
|
||||||
|
|
@ -1247,6 +1247,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor, bool commit) {
|
||||||
if (!g_pCompositor->m_sessionActive)
|
if (!g_pCompositor->m_sessionActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (g_pAnimationManager)
|
||||||
|
g_pAnimationManager->frameTick();
|
||||||
|
|
||||||
if (pMonitor->m_id == m_mostHzMonitor->m_id ||
|
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
|
*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
Add a link
Reference in a new issue