From 6adcc3aa0801db24d635e474f22e31913657229f Mon Sep 17 00:00:00 2001 From: Tim Jansen Date: Tue, 21 Jan 2003 19:55:13 +0000 Subject: [PATCH] 1. scan lines around the cursor 2. remember the last scanlines 12 that have changed 3. scan every 35th scanline (instead of every 32nd) per idle cyclus to avoid scanning too much in a cycle svn path=/trunk/kdenetwork/krfb/; revision=201789 --- krfb/rfbcontroller.cc | 4 +- krfb/xupdatescanner.cc | 110 ++++++++++++++++++++++++++++++----------- krfb/xupdatescanner.h | 11 +++-- 3 files changed, 88 insertions(+), 37 deletions(-) diff --git a/krfb/rfbcontroller.cc b/krfb/rfbcontroller.cc index ee941787..b3093a3c 100644 --- a/krfb/rfbcontroller.cc +++ b/krfb/rfbcontroller.cc @@ -555,7 +555,8 @@ void RFBController::idleSlot() QPtrList v; v.setAutoDelete(true); - scanner->searchUpdates(v); + QPoint p = QCursor::pos(); + scanner->searchUpdates(v, p.y()); Hint *h; @@ -565,7 +566,6 @@ void RFBController::idleSlot() h->right(), h->bottom()); - QPoint p = QCursor::pos(); asyncMutex.lock(); if (!closePending) defaultPtrAddEvent(0, p.x(),p.y(), server->rfbClientHead); diff --git a/krfb/xupdatescanner.cc b/krfb/xupdatescanner.cc index d2d6726a..9f38082a 100644 --- a/krfb/xupdatescanner.cc +++ b/krfb/xupdatescanner.cc @@ -22,7 +22,10 @@ * other stuff * January 10th 2002: improved hint creation (join adjacent hints) * February 20th: use only partial tiles - * + * January 21st 2003: remember last modified scanlines, and scan them and + * in every cycle, reduce scanlines to every 35th + * January 21st 2003: scan lines around the cursor in every cycle + * * Tim Jansen */ @@ -40,25 +43,35 @@ #include "xupdatescanner.h" -unsigned int scanlines[32] = { 0, 16, 8, 24, - 4, 20, 12, 28, - 10, 26, 18, 2, - 22, 6, 30, 14, - 1, 17, 9, 25, +#define SCANLINES 35 +unsigned int scanlines[SCANLINES] = { 0, 16, 8, 24, + 33, 4, 20, 12, 28, + 10, 26, 18, 34, 2, + 22, 6, 30, 14, + 1, 17, 32, 9, 25, 7, 23, 15, 31, 19, 3, 27, 11, 29, 13, 5, 21 }; #define MAX_ADJ_TOLERANCE 8 +#define MAX_RECENT_HITS 12 +unsigned int recentHitScanlines[MAX_RECENT_HITS]; + +#define CURSOR_SCANLINES 5 +int cursorScanlines[CURSOR_SCANLINES] = { + -10, -4, 0, 4, 10 +}; + + + + XUpdateScanner::XUpdateScanner(Display *_dpy, Window _window, unsigned char *_fb, int _width, int _height, int _bitsPerPixel, - int _bytesPerLine, - unsigned int _tileWidth, - unsigned int _tileHeight) : + int _bytesPerLine) : dpy(_dpy), window(_window), fb(_fb), @@ -66,8 +79,8 @@ XUpdateScanner::XUpdateScanner(Display *_dpy, height(_height), bitsPerPixel(_bitsPerPixel), bytesPerLine(_bytesPerLine), - tileWidth(_tileWidth), - tileHeight(_tileHeight), + tileWidth(32), + tileHeight(32), count (0), scanline(NULL), tile(NULL) @@ -116,6 +129,9 @@ XUpdateScanner::XUpdateScanner(Display *_dpy, shminfo_scanline.readOnly = False; XShmAttach(dpy, &shminfo_scanline); + + for (int i = 0; i < MAX_RECENT_HITS; i++) + recentHitScanlines[i] = i; }; @@ -324,35 +340,69 @@ void XUpdateScanner::createHints(QPtrList &hintList) } } -void XUpdateScanner::searchUpdates(QPtrList &hintList) +void XUpdateScanner::testScanline(int y, bool rememberHits) { + if (y < 0) + return; + if (y > (int)height) + return; + + int x = 0; + bool hit = false; + XShmGetImage(dpy, window, scanline, 0, y, AllPlanes); + + + while (x < width) { + int pixelsize = bitsPerPixel >> 3; + unsigned char *src = (unsigned char*) scanline->data + + x * pixelsize; + unsigned char *dest = fb + + y * bytesPerLine + x * pixelsize; + int w = (x + 32) > width ? (width-x) : 32; + if (memcmp(dest, src, w * pixelsize)) { + hit = true; + tileMap[(x / tileWidth) + + (y / tileHeight) * tilesX] = true; + } + x += 32; + } + + if (!rememberHits) + return; + + for (int i = 1; i < MAX_RECENT_HITS; i++) + recentHitScanlines[i-1] = recentHitScanlines[i]; + recentHitScanlines[MAX_RECENT_HITS-1] = y; +} + +void XUpdateScanner::searchUpdates(QPtrList &hintList, int ptrY) { count++; - count %= 32; + count %= SCANLINES; unsigned int i; - unsigned int x, y; + unsigned int y; for (i = 0; i < (tilesX * tilesY); i++) { tileMap[i] = false; } + // test last scanlines with hits + for (i = 0; i < MAX_RECENT_HITS; i++) + testScanline(recentHitScanlines[i], true); + + // test scanlines around the cursor + for (i = 0; i < CURSOR_SCANLINES; i++) + testScanline(ptrY+cursorScanlines[i], false); + // test last/first line of the tiles around the cursor + // (assumes tileHeight = 32) + testScanline((ptrY&0xffe0)-1, false); + testScanline((ptrY|0x1f)+1, false); + + // test every SCANLINESth scanline y = scanlines[count]; - while (y < height) { - XShmGetImage(dpy, window, scanline, 0, y, AllPlanes); - x = 0; - while (x < width) { - int pixelsize = bitsPerPixel >> 3; - unsigned char *src = (unsigned char*) scanline->data + - x * pixelsize; - unsigned char *dest = fb + - y * bytesPerLine + x * pixelsize; - int w = (x + 32) > width ? (width-x) : 32; - if (memcmp(dest, src, w * pixelsize)) - tileMap[(x / tileWidth) + - (y / tileHeight) * tilesX] = true; - x += 32; - } - y += 32; + while (y < (int)height) { + testScanline(y, true); + y += SCANLINES; } copyAllTiles(); diff --git a/krfb/xupdatescanner.h b/krfb/xupdatescanner.h index 09588cf8..e380d99d 100644 --- a/krfb/xupdatescanner.h +++ b/krfb/xupdatescanner.h @@ -69,15 +69,16 @@ class XUpdateScanner Window _window, unsigned char *_fb, int _width, int _height, - int _bitsPerPixel, int _bytesPerLine, - unsigned int _tileWidth = 32, - unsigned int _tileHeight = 32); + int _bitsPerPixel, int _bytesPerLine); ~XUpdateScanner(); - - void searchUpdates( QPtrList &hintList); + + // hitList: returns list of changes + // ptrY: ptrY: position of the cursor + void searchUpdates( QPtrList &hintList, int ptrY); private: + void testScanline(int y, bool rememberHits); bool copyTile(int x, int y, int tx, int ty); void copyAllTiles(); void flushHint(int x, int y, int &x0, Hint &hint,