aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2011-11-20 15:36:11 +0000
committerPierre Ossman <ossman@cendio.se>2011-11-20 15:36:11 +0000
commitb114cec89edf6d69c545712f29decac1631c94a2 (patch)
treede7d752926e99c906db2e718703a7a8a59b475c4
parent53fd544c2f68b2ff97fb3f5e60734b281ce75ad3 (diff)
downloadtigervnc-b114cec89edf6d69c545712f29decac1631c94a2.tar.gz
tigervnc-b114cec89edf6d69c545712f29decac1631c94a2.zip
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). git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4809 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r--common/rfb/ComparingUpdateTracker.cxx49
-rw-r--r--common/rfb/ComparingUpdateTracker.h13
-rw-r--r--common/rfb/ServerCore.cxx7
-rw-r--r--common/rfb/ServerCore.h2
-rw-r--r--common/rfb/VNCSConnectionST.cxx10
-rw-r--r--common/rfb/VNCSConnectionST.h4
-rw-r--r--common/rfb/VNCServerST.cxx25
-rw-r--r--common/rfb/VNCServerST.h2
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;