Correct check for when VRR should be active

The old calculation ignored the render time and safety margin of the
frame scheduling algorithm, which makes VRR activate properly only when
the refresh rate is much lower than the maximum refresh rate.
master
Xaver Hugl 3 years ago
parent ef9d541487
commit 724f9a5db0

@ -33,7 +33,7 @@ RenderLoopPrivate::RenderLoopPrivate(RenderLoop *q)
void RenderLoopPrivate::scheduleRepaint()
{
if (kwinApp()->isTerminating()) {
if (kwinApp()->isTerminating() || compositeTimer.isActive()) {
return;
}
if (vrrPolicy == RenderLoop::VrrPolicy::Always || (vrrPolicy == RenderLoop::VrrPolicy::Automatic && hasFullscreenSurface)) {
@ -42,25 +42,11 @@ void RenderLoopPrivate::scheduleRepaint()
presentMode = SyncMode::Fixed;
}
const std::chrono::nanoseconds vblankInterval(1'000'000'000'000ull / refreshRate);
if (presentMode == SyncMode::Adaptive) {
std::chrono::nanoseconds timeSincePresent = std::chrono::steady_clock::now().time_since_epoch() - lastPresentationTimestamp;
if (timeSincePresent > vblankInterval) {
// client renders slower than refresh rate -> immediately present
compositeTimer.start(0);
return;
}
// client renders faster than refresh rate -> normal frame scheduling
}
if (compositeTimer.isActive()) {
return;
}
const std::chrono::nanoseconds currentTime(std::chrono::steady_clock::now().time_since_epoch());
// Estimate when the next presentation will occur. Note that this is a prediction.
nextPresentationTimestamp = lastPresentationTimestamp + vblankInterval;
if (nextPresentationTimestamp < currentTime) {
if (nextPresentationTimestamp < currentTime && presentMode == SyncMode::Fixed) {
nextPresentationTimestamp = lastPresentationTimestamp
+ alignTimestamp(currentTime - lastPresentationTimestamp, vblankInterval);
}

Loading…
Cancel
Save