25-40% reduction in raw data by xupdatescanner improvement

svn path=/trunk/kdenetwork/krfb/; revision=137531
This commit is contained in:
Tim Jansen
2002-02-19 23:33:00 +00:00
parent f2040bd3b9
commit e7df26c898
3 changed files with 135 additions and 63 deletions

View File

@@ -1,3 +1,14 @@
2002-02-20 Tim Jansen <tjansen@tjansen.de>
* krfb/Makefile.am: fixed a bug for people who "make install" for the
first time (did not create share/krfb dir for eventrc)
* krfb/xupdatescanner.cc: improved scanning algorithm and renamed the file.
Result seems to be a reduction between 25% (web browsing) and 40% (text
editing) of transmitted raw data. Note that the effectiveness of some
encoders decreases with less adjacent regions, so the real reduction is
probably less.
2002-02-18 Tim Jansen <tjansen@tjansen.de>
* released 0.6

View File

@@ -25,6 +25,8 @@
* Tim Jansen <tim@tjansen.de>
*/
#include <kdebug.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
@@ -32,6 +34,7 @@
#include <X11/extensions/XShm.h>
#include <string.h>
#include <assert.h>
#include "xupdatescanner.h"
@@ -43,6 +46,7 @@ unsigned int scanlines[32] = { 0, 16, 8, 24,
7, 23, 15, 31,
19, 3, 27, 11,
29, 13, 5, 21 };
#define MAX_ADJ_TOLERANCE 8
XUpdateScanner::XUpdateScanner(Display *_dpy,
Window _window,
@@ -178,7 +182,7 @@ bool XUpdateScanner::copyTile(int x, int y, int tx, int ty)
break;
}
}
for (line = firstLine; line <= lastLine; line++) {
memcpy(sdest, ssrc, maxWidth * pixelsize );
ssrc += tile->bytes_per_line;
@@ -189,7 +193,7 @@ bool XUpdateScanner::copyTile(int x, int y, int tx, int ty)
r->firstLine = firstLine;
r->lastLine = lastLine;
return lastLine >= (maxHeight-1);
return lastLine == (maxHeight-1);
}
void XUpdateScanner::copyAllTiles()
@@ -205,14 +209,14 @@ void XUpdateScanner::copyAllTiles()
}
void XUpdateScanner::createHintFromTile(int x, int y, Hint &hint)
void XUpdateScanner::createHintFromTile(int x, int y, int th, Hint &hint)
{
unsigned int w = width - x;
unsigned int h = height - y;
if (w > tileWidth)
if (w > tileWidth)
w = tileWidth;
if (h > tileHeight)
h = tileHeight;
if (h > th)
h = th;
hint.x = x;
hint.y = y;
@@ -220,14 +224,15 @@ void XUpdateScanner::createHintFromTile(int x, int y, Hint &hint)
hint.h = h;
}
void XUpdateScanner::addTileToHint(int x, int y, Hint &hint)
void XUpdateScanner::addTileToHint(int x, int y, int th, Hint &hint)
{
// todo: refuse to add hint if this one is much smaller or bigger (use x0)
unsigned int w = width - x;
unsigned int h = height - y;
if (w > tileWidth)
w = tileWidth;
if (h > tileHeight)
h = tileHeight;
if (h > th)
h = th;
if (hint.x > x) {
hint.w += hint.x - x;
@@ -248,35 +253,82 @@ void XUpdateScanner::addTileToHint(int x, int y, Hint &hint)
}
}
void XUpdateScanner::flushHint(int x, int y, int &x0,
Hint &hint, QPtrList<Hint> &hintList)
void XUpdateScanner::extendHintY(int x, int y, int x0, Hint &hint)
{
if (x0 < 0)
return;
int h = 1;
int eh = 0;
int lastLine = -1;
int w = x - x0 + 1;
for (int i = y+1; i < tilesY; i++) {
bool lk = true;
int ll = 0;
for (int j = x0; j < x; j++) {
if (!tileMap[j + i * tilesX]) {
int idx = j + i * tilesX;
if ((!tileMap[idx]) ||
(tileRegionMap[idx].firstLine*w > MAX_ADJ_TOLERANCE)) {
lk = false;
break;
}
if (tileRegionMap[idx].lastLine > ll)
ll = tileRegionMap[idx].lastLine;
}
if (!lk)
break;
for (int j = x0; j < x; j++)
tileMap[j + i * tilesX] = false;
h++;
}
hint.h = h * tileHeight;
if ((hint.y + hint.h) > height)
h = height - hint.y;
lastLine = ll;
eh++;
if ((ll*w) > MAX_ADJ_TOLERANCE)
break;
}
if (eh == 0)
return;
hint.h += (eh-1) * tileHeight;
hint.h += lastLine + 1;
if ((hint.y + hint.h) > height)
hint.h = height - hint.y;
}
static void printStatistics(Hint &hint) {
static int snum = 0;
static float ssum = 0.0;
int oX0 = hint.x & 0xffffffe0;
int oY0 = hint.y & 0xffffffe0;
int oX2 = (hint.x+hint.w) & 0x1f;
int oY2 = (hint.y+hint.h) & 0x1f;
int oX3 = (((hint.x+hint.w) | 0x1f) + ((oX2 == 0) ? 0 : 1)) & 0xffffffe0;
int oY3 = (((hint.y+hint.h) | 0x1f) + ((oY2 == 0) ? 0 : 1)) & 0xffffffe0;
float s0 = hint.w*hint.h;
float s1 = (oX3-oX0)*(oY3-oY0);
float p = (100*s0/s1);
ssum += p;
snum++;
float avg = ssum / snum;
kdDebug() << "avg size: "<< avg <<"%"<<endl;
}
void XUpdateScanner::flushHint(int x, int y, int &x0,
Hint &hint, QPtrList<Hint> &hintList)
{
if (x0 < 0)
return;
int w = x - x0 + 1;
int th = (hint.y + hint.h) % tileHeight;
if ((th == 0) ||
((31-th)*w < MAX_ADJ_TOLERANCE))
extendHintY(x, y, x0, hint);
x0 = -1;
assert (hint.w > 0);
assert (hint.h > 0);
//printStatistics(hint);
hintList.append(new Hint(hint));
}
@@ -288,17 +340,23 @@ void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
for (int y = 0; y < tilesY; y++) {
int x;
for (x = 0; x < tilesX; x++) {
if (tileMap[x + y * tilesX]) {
int idx = x + y * tilesX;
if (tileMap[idx]) {
int ty = tileRegionMap[idx].firstLine;
int th = tileRegionMap[idx].lastLine - ty +1;
if (x0 < 0) {
createHintFromTile(x * tileWidth,
y * tileHeight,
(y * tileHeight) + ty,
th,
hint);
x0 = x;
}
else
else {
addTileToHint(x * tileWidth,
y * tileHeight,
(y * tileHeight) + ty,
th,
hint);
}
}
else
flushHint(x, y, x0, hint, hintList);

View File

@@ -64,43 +64,46 @@ struct TileChangeRegion {
class XUpdateScanner
{
public:
XUpdateScanner( Display *_dpy,
Window _window,
unsigned char *_fb,
int _width, int _height,
int _bitsPerPixel, int _bytesPerLine,
unsigned int _tileWidth = 32,
unsigned int _tileHeight = 32);
~XUpdateScanner();
bool copyTile(int x, int y, int tx, int ty);
void copyAllTiles();
void searchUpdates( QPtrList<Hint> &hintList);
void flushHint(int x, int y, int &x0, Hint &hint,
QPtrList<Hint> &hintList);
void createHints(QPtrList<Hint> &hintList);
void addTileToHint(int x, int y, Hint &hint);
void createHintFromTile(int x, int y, Hint &hint);
Display *dpy;
Window window;
unsigned char *fb;
int width, height;
int bitsPerPixel, bytesPerLine;
unsigned int tileWidth, tileHeight;
unsigned int count;
XImage *scanline;
XShmSegmentInfo shminfo_scanline;
XImage *tile;
XShmSegmentInfo shminfo_tile;
unsigned int tilesX, tilesY;
bool *tileMap;
struct TileChangeRegion *tileRegionMap;
public:
XUpdateScanner( Display *_dpy,
Window _window,
unsigned char *_fb,
int _width, int _height,
int _bitsPerPixel, int _bytesPerLine,
unsigned int _tileWidth = 32,
unsigned int _tileHeight = 32);
~XUpdateScanner();
void searchUpdates( QPtrList<Hint> &hintList);
private:
bool copyTile(int x, int y, int tx, int ty);
void copyAllTiles();
void flushHint(int x, int y, int &x0, Hint &hint,
QPtrList<Hint> &hintList);
void createHints(QPtrList<Hint> &hintList);
void addTileToHint(int x, int y, int th, Hint &hint);
void createHintFromTile(int x, int y, int th, Hint &hint);
void extendHintY(int x, int y, int x0, Hint &h);
Display *dpy;
Window window;
unsigned char *fb;
int width, height;
int bitsPerPixel, bytesPerLine;
unsigned int tileWidth, tileHeight;
unsigned int count;
XImage *scanline;
XShmSegmentInfo shminfo_scanline;
XImage *tile;
XShmSegmentInfo shminfo_tile;
unsigned int tilesX, tilesY;
bool *tileMap;
struct TileChangeRegion *tileRegionMap;
};