diff options
author | Pierre Ossman <ossman@cendio.se> | 2024-02-28 14:20:54 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2024-06-19 16:39:07 +0200 |
commit | 5242bfb39648855acd928b186b7c7b6b1f84313c (patch) | |
tree | e5aa0cbe9bbafaf688b3905c2f56a6be22993e62 | |
parent | d226d98269dca1a5c52f13a681e4740fe0a3d39d (diff) | |
download | tigervnc-5242bfb39648855acd928b186b7c7b6b1f84313c.tar.gz tigervnc-5242bfb39648855acd928b186b7c7b6b1f84313c.zip |
Keep frame clock running if waiting for frame tick
If there is something interested in synchronizing to a frame tick, then
keep the frame clock running, even if there are no updates.
This is need mainly when something starts rendering, but also when
something renders much slower than the frame clock (so it is essentially
constantly "starting"). Such an application will not draw anything until
it gets a new frame tick, which it won't get as the frame clock is
waiting for something to start drawing.
-rw-r--r-- | common/rfb/VNCServer.h | 1 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 20 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 3 | ||||
-rw-r--r-- | unix/xserver/hw/vnc/XserverDesktop.cc | 1 |
4 files changed, 20 insertions, 5 deletions
diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h index 314367eb..b49dbfe3 100644 --- a/common/rfb/VNCServer.h +++ b/common/rfb/VNCServer.h @@ -43,6 +43,7 @@ namespace rfb { virtual void unblockUpdates() = 0; virtual uint64_t getMsc() = 0; + virtual void queueMsc(uint64_t target) = 0; // setPixelBuffer() tells the server to use the given pixel buffer (and // optionally a modified screen layout). If this differs in size from diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 296ddd8e..f091ddd5 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -88,7 +88,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_) renderedCursorInvalid(false), keyRemapper(&KeyRemapper::defInstance), idleTimer(this), disconnectTimer(this), connectTimer(this), - msc(0), frameTimer(this) + msc(0), queuedMsc(0), frameTimer(this) { slog.debug("creating single-threaded server %s", name.c_str()); @@ -262,6 +262,14 @@ uint64_t VNCServerST::getMsc() return msc; } +void VNCServerST::queueMsc(uint64_t target) +{ + if (target > queuedMsc) + queuedMsc = target; + + startFrameClock(); +} + void VNCServerST::setPixelBuffer(PixelBuffer* pb_, const ScreenSet& layout) { if (comparer) @@ -634,13 +642,17 @@ void VNCServerST::handleTimeout(Timer* t) { if (t == &frameTimer) { // We keep running until we go a full interval without any updates - if (comparer->is_empty()) - return; + if (comparer->is_empty()) { + // 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); - writeUpdate(); + if (!comparer->is_empty()) + writeUpdate(); msc++; desktop->frameTick(msc); diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 719b3f36..3436d333 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -82,6 +82,7 @@ namespace rfb { virtual void blockUpdates(); virtual void unblockUpdates(); virtual uint64_t getMsc(); + virtual void queueMsc(uint64_t target); virtual void setPixelBuffer(PixelBuffer* pb, const ScreenSet& layout); virtual void setPixelBuffer(PixelBuffer* pb); virtual void setScreenLayout(const ScreenSet& layout); @@ -207,7 +208,7 @@ namespace rfb { Timer disconnectTimer; Timer connectTimer; - uint64_t msc; + uint64_t msc, queuedMsc; Timer frameTimer; }; diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 6fe055ea..eaf6f901 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -154,6 +154,7 @@ uint64_t XserverDesktop::getMsc() void XserverDesktop::queueMsc(uint64_t id, uint64_t msc) { pendingMsc[id] = msc; + server->queueMsc(msc); } void XserverDesktop::abortMsc(uint64_t id) |