diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h index 314367eb6..b49dbfe34 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 296ddd8ed..f091ddd5d 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 719b3f366..3436d333f 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 6fe055ea3..eaf6f901b 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)