mirror of
https://github.com/KDE/krfb
synced 2026-07-01 07:31:16 -07:00
25-40% reduction in raw data by xupdatescanner improvement
svn path=/trunk/kdenetwork/krfb/; revision=137531
This commit is contained in:
11
ChangeLog
11
ChangeLog
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user