summaryrefslogtreecommitdiffstats
path: root/x0vncserver
diff options
context:
space:
mode:
authorConstantin Kaplinsky <const@tightvnc.com>2005-10-19 13:57:16 +0000
committerConstantin Kaplinsky <const@tightvnc.com>2005-10-19 13:57:16 +0000
commitdc54fc1a0dab372a95c70006757bf3ce1266eee3 (patch)
treeef564606ba4841d2f4c9afedeaf5122db9649973 /x0vncserver
parent880318bf63d7640764ecd5639c7aadef952fd118 (diff)
downloadtigervnc-dc54fc1a0dab372a95c70006757bf3ce1266eee3.tar.gz
tigervnc-dc54fc1a0dab372a95c70006757bf3ce1266eee3.zip
Implemented new polling algorithm with video detection.
Continuously-changed areas like video windows would be updated with reduced rate, to improve responsiveness of other screen elements. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@355 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'x0vncserver')
-rw-r--r--x0vncserver/PollingManager.cxx97
-rw-r--r--x0vncserver/PollingManager.h6
2 files changed, 99 insertions, 4 deletions
diff --git a/x0vncserver/PollingManager.cxx b/x0vncserver/PollingManager.cxx
index 25111cdf..3c6aab92 100644
--- a/x0vncserver/PollingManager.cxx
+++ b/x0vncserver/PollingManager.cxx
@@ -29,7 +29,7 @@
#include <x0vncserver/Image.h>
#include <x0vncserver/PollingManager.h>
-IntParameter pollingType("PollingType", "Polling algorithm to use (0..2)", 2);
+IntParameter pollingType("PollingType", "Polling algorithm to use (0..3)", 3);
const int PollingManager::m_pollingOrder[32] = {
0, 16, 8, 24, 4, 20, 12, 28,
@@ -62,16 +62,32 @@ PollingManager::PollingManager(Display *dpy, Image *image,
m_rowImage = factory->newImage(m_dpy, m_width, 1);
m_tileImage = factory->newImage(m_dpy, 32, 32);
+ // FIXME: Extend the comment.
// Create a matrix with one byte per each 32x32 tile. It will be
// used to limit the rate of updates on continuously-changed screen
// areas (like video).
int numTiles = m_widthTiles * m_heightTiles;
m_statusMatrix = new char[numTiles];
memset(m_statusMatrix, 0, numTiles);
+
+ // FIXME: Extend the comment.
+ // Create a matrix with one byte per each 32x32 tile. It will be
+ // used to limit the rate of updates on continuously-changed screen
+ // areas (like video).
+ m_rateMatrix = new char[numTiles];
+ m_videoFlags = new char[numTiles];
+ m_changedFlags = new char[numTiles];
+ memset(m_rateMatrix, 0, numTiles);
+ memset(m_videoFlags, 0, numTiles);
+ memset(m_changedFlags, 0, numTiles);
}
PollingManager::~PollingManager()
{
+ delete[] m_changedFlags;
+ delete[] m_videoFlags;
+ delete[] m_rateMatrix;
+
delete[] m_statusMatrix;
}
@@ -118,11 +134,86 @@ void PollingManager::poll()
case 1:
poll_Traditional();
break;
-//case 2:
- default:
+ case 2:
poll_SkipCycles();
break;
+//case 3:
+ default:
+ poll_DetectVideo();
+ break;
+ }
+}
+
+void PollingManager::poll_DetectVideo()
+{
+ if (!m_server)
+ return;
+
+ const int GRAND_STEP_DIVISOR = 8;
+ const int VIDEO_THRESHOLD_0 = 3;
+ const int VIDEO_THRESHOLD_1 = 5;
+
+ bool grandStep = (m_pollingStep % GRAND_STEP_DIVISOR == 0);
+
+ // FIXME: Save shortcuts in member variables.
+ int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+ int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+ int bytesPerLine = m_image->xim->bytes_per_line;
+
+ Rect rect;
+ int nTilesChanged = 0;
+ int idx = 0;
+
+ for (int y = 0; y * 32 < m_height; y++) {
+ int tile_h = (m_height - y * 32 >= 32) ? 32 : m_height - y * 32;
+ if (scanLine >= tile_h)
+ break;
+ int scan_y = y * 32 + scanLine;
+ m_rowImage->get(DefaultRootWindow(m_dpy), 0, scan_y);
+ char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+ char *ptr_new = m_rowImage->xim->data;
+ for (int x = 0; x * 32 < m_width; x++) {
+ int tile_w = (m_width - x * 32 >= 32) ? 32 : m_width - x * 32;
+ int nBytes = tile_w * bytesPerPixel;
+
+ char wasChanged = (memcmp(ptr_old, ptr_new, nBytes) != 0);
+ m_rateMatrix[idx] += wasChanged;
+
+ if (grandStep) {
+ if (m_rateMatrix[idx] <= VIDEO_THRESHOLD_0) {
+ m_videoFlags[idx] = 0;
+ } else if (m_rateMatrix[idx] >= VIDEO_THRESHOLD_1) {
+ m_videoFlags[idx] = 1;
+ }
+ m_rateMatrix[idx] = 0;
+ }
+
+ m_changedFlags[idx] |= wasChanged;
+ if ( m_changedFlags[idx] && (!m_videoFlags[idx] || grandStep) ) {
+ if (tile_w == 32 && tile_h == 32) {
+ m_tileImage->get(DefaultRootWindow(m_dpy), x * 32, y * 32);
+ } else {
+ m_tileImage->get(DefaultRootWindow(m_dpy), x * 32, y * 32,
+ tile_w, tile_h);
+ }
+ m_image->updateRect(m_tileImage, x * 32, y * 32);
+ rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+ m_server->add_changed(rect);
+ nTilesChanged++;
+ m_changedFlags[idx] = 0;
+ }
+
+ if (wasChanged) {
+ }
+
+ ptr_old += nBytes;
+ ptr_new += nBytes;
+ idx++;
+ }
}
+
+ if (nTilesChanged)
+ m_server->tryUpdate();
}
void PollingManager::poll_SkipCycles()
diff --git a/x0vncserver/PollingManager.h b/x0vncserver/PollingManager.h
index 9befee9b..59eb22e0 100644
--- a/x0vncserver/PollingManager.h
+++ b/x0vncserver/PollingManager.h
@@ -43,6 +43,7 @@ public:
protected:
+ void poll_DetectVideo();
void poll_SkipCycles();
void poll_Traditional();
void poll_Dumb();
@@ -61,9 +62,12 @@ protected:
char *m_statusMatrix;
+ char *m_rateMatrix;
+ char *m_videoFlags;
+ char *m_changedFlags;
+
unsigned int m_pollingStep;
static const int m_pollingOrder[];
- static const char m_bitsSet[];
};