diff options
Diffstat (limited to 'common/rfb')
-rw-r--r-- | common/rfb/ComparingUpdateTracker.cxx | 49 | ||||
-rw-r--r-- | common/rfb/ComparingUpdateTracker.h | 13 | ||||
-rw-r--r-- | common/rfb/ServerCore.cxx | 7 | ||||
-rw-r--r-- | common/rfb/ServerCore.h | 2 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.cxx | 10 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.h | 4 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 25 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 2 |
8 files changed, 91 insertions, 21 deletions
diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx index 42a9e192..43287e07 100644 --- a/common/rfb/ComparingUpdateTracker.cxx +++ b/common/rfb/ComparingUpdateTracker.cxx @@ -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) diff --git a/common/rfb/ComparingUpdateTracker.h b/common/rfb/ComparingUpdateTracker.h index 5d2e5edf..fccc2222 100644 --- a/common/rfb/ComparingUpdateTracker.h +++ b/common/rfb/ComparingUpdateTracker.h @@ -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; }; } diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx index 27e116e3..ae2fd247 100644 --- a/common/rfb/ServerCore.cxx +++ b/common/rfb/ServerCore.cxx @@ -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 " diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h index 68d7b74b..e12a8bc8 100644 --- a/common/rfb/ServerCore.h +++ b/common/rfb/ServerCore.h @@ -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; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index d0cdf869..466d6d5c 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -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. diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h index 8742fa67..72dc59c0 100644 --- a/common/rfb/VNCSConnectionST.h +++ b/common/rfb/VNCSConnectionST.h @@ -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 diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 5c135969..1e3f61a0 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -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; +} diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 47a48019..2fed0a87 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -238,6 +238,8 @@ namespace rfb { void notifyScreenLayoutChange(VNCSConnectionST *requester); + bool getComparerState(); + QueryConnectionHandler* queryConnectionHandler; KeyRemapper* keyRemapper; bool useEconomicTranslate; |