]> source.dussan.org Git - tigervnc.git/commitdiff
Make the comparing update tracker a bit more flexible. It can now be in an
authorPierre Ossman <ossman@cendio.se>
Sun, 20 Nov 2011 15:36:11 +0000 (15:36 +0000)
committerPierre Ossman <ossman@cendio.se>
Sun, 20 Nov 2011 15:36:11 +0000 (15:36 +0000)
"auto" state where it will be enabled until we deem that the client is better
of without it (currently triggered by explicitly stating a low compression
level).

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4809 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/ComparingUpdateTracker.cxx
common/rfb/ComparingUpdateTracker.h
common/rfb/ServerCore.cxx
common/rfb/ServerCore.h
common/rfb/VNCSConnectionST.cxx
common/rfb/VNCSConnectionST.h
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index 42a9e192758c422a2b6ed55394f653da4f85ce2a..43287e077af41a8c9a0d5edc64bfb49b335e000a 100644 (file)
@@ -25,7 +25,7 @@
 using namespace rfb;
 
 ComparingUpdateTracker::ComparingUpdateTracker(PixelBuffer* buffer)
-  : fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true)
+  : fb(buffer), oldFb(fb->getPF(), 0, 0), firstCompare(true), enabled(true)
 {
     changed.assign_union(fb->getRect());
 }
@@ -37,35 +37,60 @@ ComparingUpdateTracker::~ComparingUpdateTracker()
 
 #define BLOCK_SIZE 16
 
-void ComparingUpdateTracker::compare()
+bool ComparingUpdateTracker::compare()
 {
   std::vector<Rect> rects;
   std::vector<Rect>::iterator i;
 
+  if (!enabled)
+    return false;
+
   if (firstCompare) {
     // NB: We leave the change region untouched on this iteration,
     // since in effect the entire framebuffer has changed.
     oldFb.setSize(fb->width(), fb->height());
+
     for (int y=0; y<fb->height(); y+=BLOCK_SIZE) {
       Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE));
       int srcStride;
       const rdr::U8* srcData = fb->getPixelsR(pos, &srcStride);
       oldFb.imageRect(pos, srcData, srcStride);
     }
+
     firstCompare = false;
-  } else {
-    copied.get_rects(&rects, copy_delta.x<=0, copy_delta.y<=0);
-    for (i = rects.begin(); i != rects.end(); i++)
-      oldFb.copyRect(*i, copy_delta);
 
-    changed.get_rects(&rects);
+    return false;
+  }
+
+  copied.get_rects(&rects, copy_delta.x<=0, copy_delta.y<=0);
+  for (i = rects.begin(); i != rects.end(); i++)
+    oldFb.copyRect(*i, copy_delta);
 
-    Region newChanged;
-    for (i = rects.begin(); i != rects.end(); i++)
-      compareRect(*i, &newChanged);
+  changed.get_rects(&rects);
 
-    changed = newChanged;
-  }
+  Region newChanged;
+  for (i = rects.begin(); i != rects.end(); i++)
+    compareRect(*i, &newChanged);
+
+  if (changed.equals(newChanged))
+    return false;
+
+  changed = newChanged;
+
+  return true;
+}
+
+void ComparingUpdateTracker::enable()
+{
+  enabled = true;
+}
+
+void ComparingUpdateTracker::disable()
+{
+  enabled = false;
+
+  // Make sure we update the framebuffer next time we get enabled
+  firstCompare = true;
 }
 
 void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
index 5d2e5edf24dc426d768d8435a765d68d7b178f76..fccc2222765c2d11a20dcbbcdd27b2887a90f651 100644 (file)
@@ -29,14 +29,23 @@ namespace rfb {
     ~ComparingUpdateTracker();
 
     // compare() does the comparison and reduces its changed and copied regions
-    // as appropriate.
+    // as appropriate. Returns true if the regions were altered.
 
-    virtual void compare();
+    virtual bool compare();
+
+    // enable()/disable() turns the comparing functionality on/off. With it
+    // disabled, the object will behave like a dumb update tracker (i.e.
+    // compare() will be a no-op). It is harmless to repeatedly call these
+    // methods.
+
+    virtual void enable();
+    virtual void disable();
   private:
     void compareRect(const Rect& r, Region* newchanged);
     PixelBuffer* fb;
     ManagedPixelBuffer oldFb;
     bool firstCompare;
+    bool enabled;
   };
 
 }
index 27e116e392aa49b4694eebb26d74058db578a3f1..ae2fd2474de5287527a48d0b64bf617264eb2498 100644 (file)
@@ -47,10 +47,11 @@ rfb::IntParameter rfb::Server::clientWaitTimeMillis
  "The number of milliseconds to wait for a client which is no longer "
  "responding",
  20000, 0);
-rfb::BoolParameter rfb::Server::compareFB
+rfb::IntParameter rfb::Server::compareFB
 ("CompareFB",
- "Perform pixel comparison on framebuffer to reduce unnecessary updates",
- false);
+ "Perform pixel comparison on framebuffer to reduce unnecessary updates "
+ "(0: never, 1: always, 2: auto)",
+ 2);
 rfb::BoolParameter rfb::Server::protocol3_3
 ("Protocol3.3",
  "Always use protocol version 3.3 for backwards compatibility with "
index 68d7b74b33bb147231e037975fab05e0bf3ab752..e12a8bc8a57e3d6b441842364406f13cb60e3265 100644 (file)
@@ -37,7 +37,7 @@ namespace rfb {
     static IntParameter maxConnectionTime;
     static IntParameter maxIdleTime;
     static IntParameter clientWaitTimeMillis;
-    static BoolParameter compareFB;
+    static IntParameter compareFB;
     static BoolParameter protocol3_3;
     static BoolParameter alwaysShared;
     static BoolParameter neverShared;
index d0cdf869943610eab32d76e791331132689950a5..466d6d5c835d72033dcbb65ed92128946dee3580 100644 (file)
@@ -326,6 +326,16 @@ int VNCSConnectionST::checkIdleTimeout()
   return secsToMillis(timeLeft);
 }
 
+
+bool VNCSConnectionST::getComparerState()
+{
+  // We interpret a low compression level as an indication that the client
+  // wants to prioritise CPU usage over bandwidth, and hence disable the
+  // comparing update tracker.
+  return (cp.compressLevel == -1) || (cp.compressLevel > 1);
+}
+
+
 // renderedCursorChange() is called whenever the server-side rendered cursor
 // changes shape or position.  It ensures that the next update will clean up
 // the old rendered cursor and if necessary draw the new rendered cursor.
index 8742fa6765ba67b810548675116dee9c6e20545d..72dc59c0e8f2c1ea9b4895a9a0f8df44a19fc46a 100644 (file)
@@ -85,6 +85,10 @@ namespace rfb {
     // The following methods never throw exceptions nor do they ever delete the
     // SConnectionST object.
 
+    // getComparerState() returns if this client would like the framebuffer
+    // comparer to be enabled.
+    bool getComparerState();
+
     // renderedCursorChange() is called whenever the server-side rendered
     // cursor changes shape or position.  It ensures that the next update will
     // clean up the old rendered cursor and if necessary draw the new rendered
index 5c13596983a7fac5e4cb80b032e2a3f638cfeb3a..1e3f61a08da0e5708677f326d45fdf016db277f9 100644 (file)
@@ -596,10 +596,13 @@ bool VNCServerST::checkUpdate()
 
   pb->grabRegion(toCheck);
 
-  if (rfb::Server::compareFB) {
-    comparer->compare();
+  if (getComparerState())
+    comparer->enable();
+  else
+    comparer->disable();
+
+  if (comparer->compare())
     comparer->getUpdateInfo(&ui, pb->getRect());
-  }
 
   if (renderCursor) {
     pb->getImage(renderedCursor.data,
@@ -665,3 +668,19 @@ void VNCServerST::notifyScreenLayoutChange(VNCSConnectionST* requester)
     (*ci)->screenLayoutChangeOrClose(reasonOtherClient);
   }
 }
+
+bool VNCServerST::getComparerState()
+{
+  if (rfb::Server::compareFB == 0)
+    return false;
+  if (rfb::Server::compareFB != 2)
+    return true;
+
+  std::list<VNCSConnectionST*>::iterator ci, ci_next;
+  for (ci=clients.begin();ci!=clients.end();ci=ci_next) {
+    ci_next = ci; ci_next++;
+    if ((*ci)->getComparerState())
+      return true;
+  }
+  return false;
+}
index 47a4801972a559793469ee70ba49a17f247f4421..2fed0a87f104cd64538f6061abe49245305d7db5 100644 (file)
@@ -238,6 +238,8 @@ namespace rfb {
 
     void notifyScreenLayoutChange(VNCSConnectionST *requester);
 
+    bool getComparerState();
+
     QueryConnectionHandler* queryConnectionHandler;
     KeyRemapper* keyRemapper;
     bool useEconomicTranslate;