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
wilder/Plasma/6.2
Xaver Hugl 2 years ago
parent 06db626fc4
commit 31ebdb73a0
  1. 2
      src/core/renderloop.cpp
  2. 12
      src/scene/surfaceitem.cpp
  3. 4
      src/scene/surfaceitem.h

@ -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;
}
}

@ -104,13 +104,12 @@ static QRegion expandRegion(const QRegion &region, const QMargins &padding)
void SurfaceItem::addDamage(const QRegion &region)
{
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;
}
}

@ -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<std::chrono::nanoseconds> m_lastDamageTimeDiffs;
std::optional<std::chrono::steady_clock::time_point> m_lastDamage;
double m_refreshRate = 0;
std::chrono::nanoseconds m_frameTimeEstimation = std::chrono::days(1000);
};
class KWIN_EXPORT SurfaceTexture

Loading…
Cancel
Save