core/renderjournal: improve render time heuristics
Instead of giving the rolling average for render times a special case for when render time suddenly increases, detect how stable render times are. If they're volatile and increase a lot, increase the predicated render time beyond the spike, as more render time spikes are likely to follow. CCBUG: 477959
This commit is contained in:
parent
7ba7ddfee8
commit
9822e75fbf
3 changed files with 24 additions and 14 deletions
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "renderjournal.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -13,22 +15,29 @@ RenderJournal::RenderJournal()
|
|||
{
|
||||
}
|
||||
|
||||
void RenderJournal::add(std::chrono::nanoseconds renderTime)
|
||||
static std::chrono::nanoseconds mix(std::chrono::nanoseconds duration1, std::chrono::nanoseconds duration2, double ratio)
|
||||
{
|
||||
if (renderTime > m_result || !m_lastAdd) {
|
||||
m_result = renderTime;
|
||||
} else {
|
||||
static constexpr std::chrono::nanoseconds timeConstant = std::chrono::milliseconds(500);
|
||||
const auto timeDifference = std::chrono::steady_clock::now() - *m_lastAdd;
|
||||
const double ratio = std::min(0.1, double(timeDifference.count()) / double(timeConstant.count()));
|
||||
m_result = std::chrono::nanoseconds(int64_t(renderTime.count() * ratio + m_result.count() * (1 - ratio)));
|
||||
}
|
||||
m_lastAdd = std::chrono::steady_clock::now();
|
||||
return std::chrono::nanoseconds(int64_t(std::round(duration1.count() * ratio + duration2.count() * (1 - ratio))));
|
||||
}
|
||||
|
||||
void RenderJournal::add(std::chrono::nanoseconds renderTime, std::chrono::nanoseconds presentationTimestamp)
|
||||
{
|
||||
const auto timeDifference = m_lastAdd ? presentationTimestamp - *m_lastAdd : 10s;
|
||||
m_lastAdd = presentationTimestamp;
|
||||
|
||||
static constexpr std::chrono::nanoseconds varianceTimeConstant = 3s;
|
||||
const double varianceRatio = std::clamp(timeDifference.count() / double(varianceTimeConstant.count()), 0.1, 1.0);
|
||||
const auto renderTimeDiff = std::max(renderTime - m_result, 0ns);
|
||||
m_variance = std::max(mix(renderTimeDiff, m_variance, varianceRatio), renderTimeDiff);
|
||||
|
||||
static constexpr std::chrono::nanoseconds timeConstant = 500ms;
|
||||
const double ratio = std::clamp(timeDifference.count() / double(timeConstant.count()), 0.1, 1.0);
|
||||
m_result = mix(renderTime, m_result, ratio);
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds RenderJournal::result() const
|
||||
{
|
||||
return m_result;
|
||||
return m_result + m_variance * 2;
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -23,13 +23,14 @@ class KWIN_EXPORT RenderJournal
|
|||
public:
|
||||
RenderJournal();
|
||||
|
||||
void add(std::chrono::nanoseconds renderTime);
|
||||
void add(std::chrono::nanoseconds renderTime, std::chrono::nanoseconds presentationTimestamp);
|
||||
|
||||
std::chrono::nanoseconds result() const;
|
||||
|
||||
private:
|
||||
std::chrono::nanoseconds m_result{0};
|
||||
std::optional<std::chrono::steady_clock::time_point> m_lastAdd;
|
||||
std::chrono::nanoseconds m_variance{0};
|
||||
std::optional<std::chrono::nanoseconds> m_lastAdd;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
|
@ -97,7 +97,7 @@ void RenderLoopPrivate::notifyFrameCompleted(std::chrono::nanoseconds timestamp,
|
|||
|
||||
notifyVblank(timestamp);
|
||||
|
||||
renderJournal.add(renderTime);
|
||||
renderJournal.add(renderTime, timestamp);
|
||||
if (!inhibitCount) {
|
||||
maybeScheduleRepaint();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue