From 31ebdb73a0022bebfc0637d768bb52bd29c969d5 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Tue, 6 Feb 2024 21:44:38 +0100 Subject: [PATCH] scene/surfaceitem: change refresh rate estimation to frame time estimation This is both more direct and avoids divisions by durations that can potentially be zero BUG: 480971 --- src/core/renderloop.cpp | 2 +- src/scene/surfaceitem.cpp | 12 +++++------- src/scene/surfaceitem.h | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/renderloop.cpp b/src/core/renderloop.cpp index 48339ec499..5e3a74c7fc 100644 --- a/src/core/renderloop.cpp +++ b/src/core/renderloop.cpp @@ -204,7 +204,7 @@ void RenderLoop::scheduleRepaint(Item *item) const bool vrr = d->presentationMode == PresentationMode::AdaptiveSync || d->presentationMode == PresentationMode::AdaptiveAsync; if (vrr && workspace()->activeWindow() && d->output) { Window *const activeWindow = workspace()->activeWindow(); - if (activeWindow->isOnOutput(d->output) && activeWindow->surfaceItem() && item != activeWindow->surfaceItem() && activeWindow->surfaceItem()->refreshRateEstimation() >= 30) { + if (activeWindow->isOnOutput(d->output) && activeWindow->surfaceItem() && item != activeWindow->surfaceItem() && activeWindow->surfaceItem()->frameTimeEstimation() <= std::chrono::nanoseconds(1'000'000'000) / 30) { return; } } diff --git a/src/scene/surfaceitem.cpp b/src/scene/surfaceitem.cpp index 5a32a0add0..4404dbc3c6 100644 --- a/src/scene/surfaceitem.cpp +++ b/src/scene/surfaceitem.cpp @@ -104,13 +104,12 @@ static QRegion expandRegion(const QRegion ®ion, const QMargins &padding) void SurfaceItem::addDamage(const QRegion ®ion) { if (m_lastDamage) { - const auto diff = std::max(std::chrono::steady_clock::now() - *m_lastDamage, 10'000ns); + const auto diff = std::chrono::steady_clock::now() - *m_lastDamage; m_lastDamageTimeDiffs.push_back(diff); if (m_lastDamageTimeDiffs.size() > 100) { m_lastDamageTimeDiffs.pop_front(); } - const auto average = std::accumulate(m_lastDamageTimeDiffs.begin(), m_lastDamageTimeDiffs.end(), 0ns) / m_lastDamageTimeDiffs.size(); - m_refreshRate = 1'000'000'000ns / average; + m_frameTimeEstimation = std::accumulate(m_lastDamageTimeDiffs.begin(), m_lastDamageTimeDiffs.end(), 0ns) / m_lastDamageTimeDiffs.size(); } m_lastDamage = std::chrono::steady_clock::now(); m_damage += region; @@ -261,14 +260,13 @@ void SurfaceItem::freeze() { } -double SurfaceItem::refreshRateEstimation() const +std::chrono::nanoseconds SurfaceItem::frameTimeEstimation() const { if (m_lastDamage) { const auto diff = std::chrono::steady_clock::now() - *m_lastDamage; - const double refreshRate = std::chrono::nanoseconds(1'000'000'000) / diff; - return std::min(m_refreshRate, refreshRate); + return std::max(m_frameTimeEstimation, diff); } else { - return m_refreshRate; + return m_frameTimeEstimation; } } diff --git a/src/scene/surfaceitem.h b/src/scene/surfaceitem.h index 619517268f..5dfcfd0ad1 100644 --- a/src/scene/surfaceitem.h +++ b/src/scene/surfaceitem.h @@ -58,7 +58,7 @@ public: virtual void freeze(); - double refreshRateEstimation() const; + std::chrono::nanoseconds frameTimeEstimation() const; Q_SIGNALS: void damaged(); @@ -81,7 +81,7 @@ protected: int m_referencePixmapCounter = 0; std::deque m_lastDamageTimeDiffs; std::optional m_lastDamage; - double m_refreshRate = 0; + std::chrono::nanoseconds m_frameTimeEstimation = std::chrono::days(1000); }; class KWIN_EXPORT SurfaceTexture