The server now only sends updates for those regions that were encoded with 
lossy JPEG.
---

Hello,

        this is the second iteration of automatic lossless refresh. It applies 
*on top* of the previous patch and adds smart updates by tracking which of the 
updates were done in a lossy manner (JPEG).       
 common/rfb/SMsgWriter.cxx       |   10 +++++++
 common/rfb/SMsgWriter.h         |    3 ++
 common/rfb/TightEncoder.h       |    4 +++
 common/rfb/VNCSConnectionST.cxx |   61 ++++++++++++++++++++++++---------------
 common/rfb/tightEncode.h        |    5 ++++
 5 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index f47f3ee..b53c03b 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -25,6 +25,7 @@
 #include <rfb/UpdateTracker.h>
 #include <rfb/SMsgWriter.h>
 #include <rfb/LogWriter.h>
+#include <rfb/TightEncoder.h>
 
 using namespace rfb;
 
@@ -214,3 +215,12 @@ int SMsgWriter::bpp()
 {
   return cp->pf().bpp;
 }
+
+SimpleUpdateTracker *SMsgWriter::getLossyRegions()
+{
+  if (cp->currentEncoding() != encodingTight)
+    return NULL;
+
+  TightEncoder *e = dynamic_cast<TightEncoder *>(encoders[encodingTight]);
+  return &(e->lossy_tracker);
+}
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index 3933b38..4ecc998 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -40,6 +40,7 @@ namespace rfb {
   class ColourMap;
   class Region;
   class UpdateInfo;
+  class SimpleUpdateTracker;
 
   class WriteSetCursorCallback {
   public:
@@ -171,6 +172,8 @@ namespace rfb {
     int getBytesSent(int encoding) { return bytesSent[encoding]; }
     rdr::U64 getRawBytesEquivalent()    { return rawBytesEquivalent; }
 
+    SimpleUpdateTracker *getLossyRegions();
+
     int imageBufIdealSize;
 
   protected:
diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h
index 10ca761..62dccb3 100644
--- a/common/rfb/TightEncoder.h
+++ b/common/rfb/TightEncoder.h
@@ -23,6 +23,7 @@
 #include <rdr/ZlibOutStream.h>
 #include <rfb/TransImageGetter.h>
 #include <rfb/Encoder.h>
+#include <rfb/UpdateTracker.h>
 
 // FIXME: Check if specifying extern "C" is really necessary.
 #include <stdio.h>
@@ -85,6 +86,8 @@ namespace rfb {
     virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
     virtual ~TightEncoder();
 
+    SimpleUpdateTracker lossy_tracker;
+
   private:
     TightEncoder(SMsgWriter* writer);
     bool checkSolidTile(Rect& r, rdr::U32* colorPtr, bool needSameColor);
@@ -155,6 +158,7 @@ namespace rfb {
     const TIGHT_CONF* pconf;
     int jpegQuality;
     JPEG_SUBSAMP jpegSubsampling;
+
   };
 
 }
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 11a6ced..096fad5 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -36,6 +36,7 @@
 #include <rfb/fenceTypes.h>
 #include <rfb/ServerCore.h>
 #include <rfb/ComparingUpdateTracker.h>
+#include <rfb/UpdateTracker.h>
 #include <rfb/KeyRemapper.h>
 #define XK_MISCELLANY
 #define XK_XKB_KEYS
@@ -1112,8 +1113,9 @@ void VNCSConnectionST::writeFramebufferUpdate()
 
     requested.clear();
 
-       if (rfb::Server::automaticRefreshDelay > 0)
+       if (rfb::Server::automaticRefreshDelay > 0 && cp.currentEncoding() == 
encodingTight) {
       refreshTimer.start(rfb::Server::automaticRefreshDelay);
+    }
   }
 
 out:
@@ -1244,28 +1246,41 @@ int VNCSConnectionST::getStatus()
 
 void VNCSConnectionST::automaticLosslessRefresh(void)
 {
-    // Automatic lossless refresh using JPEG Q95, 1X chroma sampling
-    int q = cp.qualityLevel, fq = cp.fineQualityLevel;
-    JPEG_SUBSAMP subsampling = cp.subsampling;
-    bool noJpeg = cp.noJpeg;
-
-    if (Server::automaticRefreshQuality >= 10) {
-      cp.noJpeg = true;
-      cp.qualityLevel = -1;
-    } else {
-      cp.qualityLevel = Server::automaticRefreshQuality;
-      cp.fineQualityLevel = 5 + cp.qualityLevel * 10;
-      cp.subsampling = SUBSAMP_NONE;
-    }
+  // Automatic lossless refresh using JPEG Q95, 1X chroma sampling
+  int q = cp.qualityLevel, fq = cp.fineQualityLevel;
+  JPEG_SUBSAMP subsampling = cp.subsampling;
+  bool noJpeg = cp.noJpeg;
+
+  if (Server::automaticRefreshQuality >= 10) {
+    cp.noJpeg = true;
+    cp.qualityLevel = -1;
+  } else {
+    cp.qualityLevel = Server::automaticRefreshQuality;
+    cp.fineQualityLevel = 5 + cp.qualityLevel * 10;
+    cp.subsampling = SUBSAMP_NONE;
+  }
 
-    // Update all the screen (TODO: be smarter)
-    updates.add_changed(Rect(0, 0, cp.width, cp.height));
-    writeFramebufferUpdate();
-    refreshTimer.stop();
+  // Update the regions which had been sent with lossy compression
+  SimpleUpdateTracker *lossy_tracker = writer()->getLossyRegions();
+
+  UpdateInfo ui;
+  lossy_tracker->getUpdateInfo(&ui, Region(Rect(0, 0, 10000, 10000))); 
+  if (!ui.is_empty()) {
+    std::vector<Rect> rects;
+    std::vector<Rect>::const_iterator i;
+    ui.changed.get_rects(&rects);
+    for (i = rects.begin(); i != rects.end(); i++) {
+      updates.add_changed(*i);
+    }
+  }
 
-    // Reset to previous compression settings
-    cp.qualityLevel = q;
-    cp.fineQualityLevel = fq;
-    cp.subsampling = subsampling;
-    cp.noJpeg = noJpeg;
+  writeFramebufferUpdate();
+  refreshTimer.stop();
+  lossy_tracker->clear();
+
+  // Reset to previous compression settings
+  cp.qualityLevel = q;
+  cp.fineQualityLevel = fq;
+  cp.subsampling = subsampling;
+  cp.noJpeg = noJpeg;
 }
diff --git a/common/rfb/tightEncode.h b/common/rfb/tightEncode.h
index 446d45e..5c46879 100644
--- a/common/rfb/tightEncode.h
+++ b/common/rfb/tightEncode.h
@@ -248,23 +248,28 @@ void TIGHT_ENCODE (const Rect& r, rdr::OutStream *os, 
bool forceSolid)
 #if (BPP != 8)
     if (jpegQuality != -1) {
       encodeJpegRect(r, os);
+      lossy_tracker.add_changed(Region(r));
       break;
     }
 #endif
     ENCODE_FULLCOLOR_RECT(pixels, r, os);
+    lossy_tracker.subtract(Region(r));
     break;
   case 1:
     // Solid rectangle
     ENCODE_SOLID_RECT(pixels, os);
+    lossy_tracker.subtract(Region(r));
     break;
   case 2:
     // Two-color rectangle
     ENCODE_MONO_RECT(pixels, r, os);
+    lossy_tracker.subtract(Region(r));
     break;
 #if (BPP != 8)
   default:
     // Up to 256 different colors
     ENCODE_INDEXED_RECT(pixels, r, os);
+    lossy_tracker.subtract(Region(r));
 #endif
   }
 }
-- 
1.7.9.2

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Tigervnc-devel mailing list
Tigervnc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-devel

Reply via email to