From 28c3f121613807df6d53dde9ac653916dcf8902d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 19 Feb 2024 15:28:12 +0100 Subject: [PATCH] Slow down fake clock when no clients Run the frame clock at a slow 1 Hz if there are no clients connected. This is similar to what a normal X server does when the screen is blanked, and should keep applications waiting for the frame tick happy. Note that we still only keep the frame clock running if there is any application that are interested in it. Otherwise we still stop it completely. --- common/rfb/VNCServerST.cxx | 43 ++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index f091ddd5d..72cf942d1 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -250,11 +250,9 @@ void VNCServerST::unblockUpdates() blockCounter--; - // Restart the frame clock if we have updates - if (blockCounter == 0) { - if (!comparer->is_empty()) - startFrameClock(); - } + // Restart the frame clock in case we have updates + if (blockCounter == 0) + startFrameClock(); } uint64_t VNCServerST::getMsc() @@ -641,17 +639,26 @@ SConnection* VNCServerST::getConnection(network::Socket* sock) { void VNCServerST::handleTimeout(Timer* t) { if (t == &frameTimer) { - // We keep running until we go a full interval without any updates - if (comparer->is_empty()) { + int timeout; + + // We keep running until we go a full interval without any updates, + // or there are no active clients anymore + if (comparer->is_empty() || !desktopStarted) { // Unless something waits for us to advance the frame count if (queuedMsc < msc) return; } // If this is the first iteration then we need to adjust the timeout - frameTimer.repeat(1000/rfb::Server::frameRate); + timeout = 1000/rfb::Server::frameRate; - if (!comparer->is_empty()) + // If there are no clients, then slow down the clock + if (!desktopStarted) + timeout = 1000; + + frameTimer.repeat(timeout); + + if (!comparer->is_empty() && desktopStarted) writeUpdate(); msc++; @@ -737,6 +744,12 @@ void VNCServerST::startDesktop() // stopped, so flush those out if (!comparer->is_empty()) writeUpdate(); + // If the frame clock is running, then it will be running slowly, + // so give it a kick to run at normal speed right away + if (frameTimer.isStarted()) { + stopFrameClock(); + startFrameClock(); + } } } @@ -746,7 +759,6 @@ void VNCServerST::stopDesktop() slog.debug("stopping desktop"); desktopStarted = false; desktop->stop(); - stopFrameClock(); } } @@ -774,9 +786,18 @@ void VNCServerST::startFrameClock() return; if (blockCounter > 0) return; - if (!desktopStarted) + + // Anyone actually interested in frames? + if (comparer->is_empty() && (queuedMsc <= msc)) return; + // Run the frame clock very slowly if there are no clients to actually + // send updates to + if (!desktopStarted) { + frameTimer.start(1000); + return; + } + // The first iteration will be just half a frame as we get a very // unstable update rate if we happen to be perfectly in sync with // the application's update rate