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