]> source.dussan.org Git - tigervnc.git/commitdiff
Implement proper support for fences in the server.
authorPierre Ossman <ossman@cendio.se>
Mon, 14 Nov 2011 15:54:30 +0000 (15:54 +0000)
committerPierre Ossman <ossman@cendio.se>
Mon, 14 Nov 2011 15:54:30 +0000 (15:54 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4799 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/VNCSConnectionST.cxx
common/rfb/VNCSConnectionST.h

index 30d9b6ad57b79736bc14d3eb572e69e5b75d0ffe..12dcf047ca98ef94c586ef2644fdf6bc39768ee9 100644 (file)
@@ -22,6 +22,7 @@
 #include <rfb/LogWriter.h>
 #include <rfb/Security.h>
 #include <rfb/screenTypes.h>
+#include <rfb/fenceTypes.h>
 #include <rfb/ServerCore.h>
 #include <rfb/ComparingUpdateTracker.h>
 #include <rfb/KeyRemapper.h>
@@ -35,7 +36,9 @@ static LogWriter vlog("VNCSConnST");
 
 VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
                                    bool reverse)
-  : SConnection(reverse), sock(s), inProcessMessages(false), server(server_),
+  : SConnection(reverse), sock(s), inProcessMessages(false),
+    syncFence(false), fenceFlags(0), fenceDataLen(0), fenceData(NULL),
+    server(server_),
     updates(false), image_getter(server->useEconomicTranslate),
     drawRenderedCursor(false), removeRenderedCursor(false),
     updateTimer(this), pointerEventTime(0),
@@ -70,6 +73,7 @@ VNCSConnectionST::~VNCSConnectionST()
   // Remove this client from the server
   server->clients.remove(this);
 
+  delete [] fenceData;
 }
 
 
@@ -121,6 +125,10 @@ void VNCSConnectionST::processMessages()
 
     while (getInStream()->checkNoWait(1)) {
       processMsg();
+      if (syncFence) {
+        writer()->writeFence(fenceFlags, fenceDataLen, fenceData);
+        syncFence = false;
+      }
     }
 
     // Flush out everything in case we go idle after this.
@@ -566,6 +574,42 @@ void VNCSConnectionST::setInitialColourMap()
   setColourMapEntries(0, 0);
 }
 
+void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
+{
+  if (flags & fenceFlagRequest) {
+    if (flags & fenceFlagSyncNext) {
+      if (syncFence)
+        vlog.error("Fence trying to synchronise another fence");
+
+      syncFence = true;
+
+      fenceFlags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter | fenceFlagSyncNext);
+      fenceDataLen = len;
+      delete [] fenceData;
+      if (len > 0) {
+        fenceData = new char[len];
+        memcpy(fenceData, data, len);
+      }
+
+      return;
+    }
+
+    // We handle everything synchronously so we trivially honor these modes
+    flags = flags & (fenceFlagBlockBefore | fenceFlagBlockAfter);
+
+    writer()->writeFence(flags, len, data);
+    return;
+  }
+
+  switch (len) {
+  case 0:
+    // Initial dummy fence;
+    break;
+  default:
+    vlog.error("Fence response of unexpected size received");
+  }
+}
+
 // supportsLocalCursor() is called whenever the status of
 // cp.supportsLocalCursor has changed.  If the client does now support local
 // cursor, we make sure that the old server-side rendered cursor is cleaned up
@@ -581,6 +625,11 @@ void VNCSConnectionST::supportsLocalCursor()
   }
 }
 
+void VNCSConnectionST::supportsFence()
+{
+  writer()->writeFence(fenceFlagRequest, 0, NULL);
+}
+
 void VNCSConnectionST::writeSetCursorCallback()
 {
   if (cp.supportsLocalXCursor) {
@@ -642,6 +691,12 @@ void VNCSConnectionST::writeFramebufferUpdate()
 {
   updateTimer.stop();
 
+  // We're in the middle of processing a command that's supposed to be
+  // synchronised. Allowing an update to slip out right now might violate
+  // that synchronisation.
+  if (syncFence)
+    return;
+
   // We try to aggregate responses, so don't send out anything whilst we
   // still have incoming messages. processMessages() will give us another
   // chance to run once things are idle.
index 5a007ee9d31f551f867a1fe6b3f1b78f410034d7..e06522b9e6a4f7e0c4f4b66a1c446f70fd833ad9 100644 (file)
@@ -133,7 +133,9 @@ namespace rfb {
     virtual void setDesktopSize(int fb_width, int fb_height,
                                 const ScreenSet& layout);
     virtual void setInitialColourMap();
+    virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
     virtual void supportsLocalCursor();
+    virtual void supportsFence();
 
     // setAccessRights() allows a security package to limit the access rights
     // of a VNCSConnectioST to the server.  These access rights are applied
@@ -168,6 +170,11 @@ namespace rfb {
 
     bool inProcessMessages;
 
+    bool syncFence;
+    rdr::U32 fenceFlags;
+    unsigned fenceDataLen;
+    char *fenceData;
+
     VNCServerST* server;
     SimpleUpdateTracker updates;
     TransImageGetter image_getter;