Revision: 4809 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4809&view=rev Author: ossman_ Date: 2011-11-20 15:36:11 +0000 (Sun, 20 Nov 2011) Log Message: ----------- Make the comparing update tracker a bit more flexible. It can now be in an "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).
Modified Paths: -------------- trunk/common/rfb/ComparingUpdateTracker.cxx trunk/common/rfb/ComparingUpdateTracker.h trunk/common/rfb/ServerCore.cxx trunk/common/rfb/ServerCore.h trunk/common/rfb/VNCSConnectionST.cxx trunk/common/rfb/VNCSConnectionST.h trunk/common/rfb/VNCServerST.cxx trunk/common/rfb/VNCServerST.h Modified: trunk/common/rfb/ComparingUpdateTracker.cxx =================================================================== --- trunk/common/rfb/ComparingUpdateTracker.cxx 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/ComparingUpdateTracker.cxx 2011-11-20 15:36:11 UTC (rev 4809) @@ -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,37 +37,62 @@ #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; + } - Region newChanged; - for (i = rects.begin(); i != rects.end(); i++) - compareRect(*i, &newChanged); + 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 = newChanged; - } + changed.get_rects(&rects); + + 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) { if (!r.enclosed_by(fb->getRect())) { Modified: trunk/common/rfb/ComparingUpdateTracker.h =================================================================== --- trunk/common/rfb/ComparingUpdateTracker.h 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/ComparingUpdateTracker.h 2011-11-20 15:36:11 UTC (rev 4809) @@ -29,14 +29,23 @@ ~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; }; } Modified: trunk/common/rfb/ServerCore.cxx =================================================================== --- trunk/common/rfb/ServerCore.cxx 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/ServerCore.cxx 2011-11-20 15:36:11 UTC (rev 4809) @@ -47,10 +47,11 @@ "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 " Modified: trunk/common/rfb/ServerCore.h =================================================================== --- trunk/common/rfb/ServerCore.h 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/ServerCore.h 2011-11-20 15:36:11 UTC (rev 4809) @@ -37,7 +37,7 @@ 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; Modified: trunk/common/rfb/VNCSConnectionST.cxx =================================================================== --- trunk/common/rfb/VNCSConnectionST.cxx 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/VNCSConnectionST.cxx 2011-11-20 15:36:11 UTC (rev 4809) @@ -326,6 +326,16 @@ 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. Modified: trunk/common/rfb/VNCSConnectionST.h =================================================================== --- trunk/common/rfb/VNCSConnectionST.h 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/VNCSConnectionST.h 2011-11-20 15:36:11 UTC (rev 4809) @@ -85,6 +85,10 @@ // 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 Modified: trunk/common/rfb/VNCServerST.cxx =================================================================== --- trunk/common/rfb/VNCServerST.cxx 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/VNCServerST.cxx 2011-11-20 15:36:11 UTC (rev 4809) @@ -596,10 +596,13 @@ 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 @@ (*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; +} Modified: trunk/common/rfb/VNCServerST.h =================================================================== --- trunk/common/rfb/VNCServerST.h 2011-11-17 10:19:19 UTC (rev 4808) +++ trunk/common/rfb/VNCServerST.h 2011-11-20 15:36:11 UTC (rev 4809) @@ -238,6 +238,8 @@ void notifyScreenLayoutChange(VNCSConnectionST *requester); + bool getComparerState(); + QueryConnectionHandler* queryConnectionHandler; KeyRemapper* keyRemapper; bool useEconomicTranslate; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense. http://p.sf.net/sfu/splunk-novd2d _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits