]> source.dussan.org Git - tigervnc.git/commitdiff
Slow down fake clock when no clients 1769/head
authorPierre Ossman <ossman@cendio.se>
Mon, 19 Feb 2024 14:28:12 +0000 (15:28 +0100)
committerPierre Ossman <ossman@cendio.se>
Wed, 19 Jun 2024 14:39:07 +0000 (16:39 +0200)
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

index f091ddd5d26967a0f98ee482f1e50a9adf07c4b7..72cf942d18cb906996523a1046762525a89445ce 100644 (file)
@@ -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