Commit 94b092cd authored by runge's avatar runge

x11vnc: -8to24 more speedups; tunables for very slow machines.

parent d0ef1285
......@@ -17,7 +17,7 @@ static int check_pointer_in_depth24(void);
static void parse_cmap8to24(void);
static void set_poll_fb(void);
static int check_depth(Window win, Window top, int doall);
static int check_depth_win(Window win, Window top, XWindowAttributes attr);
static int check_depth_win(Window win, Window top, XWindowAttributes *attr);
static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w);
static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod);
static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod);
......@@ -27,7 +27,7 @@ static void mark_rgn_rects(sraRegionPtr mod);
static int get_8bpp_regions(int validate);
static int get_cmap(int j, Colormap cmap);
static void do_8bpp_region(int n, sraRegionPtr mark);
static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth);
static XImage *cmap_xi(XImage *xi, Window win, int win_depth);
static void transform_rect(sraRect rect, Window win, int win_depth, int cm);
/* struct for keeping info about the 8bpp windows: */
......@@ -41,6 +41,7 @@ typedef struct window8 {
Colormap cmap;
Bool map_installed;
int fetched;
double last_fetched;
sraRegionPtr clip_region;
} window8bpp_t;
......@@ -50,21 +51,59 @@ enum mark_8bpp_modes {
MARK_8BPP_TOP
};
#define NCOLOR 256
static Colormap root_cmap = 0;
static unsigned int root_rgb[NCOLOR];
static void set_root_cmap(void) {
static time_t last_set = 0;
time_t now = time(0);
XWindowAttributes attr;
static XColor color[NCOLOR];
int redo = 0;
if (now > last_set + 5) {
root_cmap = 0;
if (now > last_set + 10) {
redo = 1;
}
if (! root_cmap) {
if (! root_cmap || redo) {
X_LOCK;
if (valid_window(window, &attr, 1)) {
if (! valid_window(window, &attr, 1)) {
X_UNLOCK;
return;
}
if (attr.colormap) {
int i, ncells = NCOLOR;
for (i=0; i < ncells; i++) {
color[i].pixel = i;
color[i].pad = 0;
}
last_set = now;
root_cmap = attr.colormap;
XQueryColors(dpy, root_cmap, color, ncells);
for (i=0; i < ncells; i++) {
unsigned int red, green, blue;
/* strip out highest 8 bits of values: */
red = (color[i].red & 0xff00) >> 8;
green = (color[i].green & 0xff00) >> 8;
blue = (color[i].blue & 0xff00) >> 8;
/*
* the maxes should be at 255 already,
* but just in case...
*/
red = (main_red_max * red )/255;
green = (main_green_max * green)/255;
blue = (main_blue_max * blue )/255;
/* shift them over and or together for value */
red = red << main_red_shift;
green = green << main_green_shift;
blue = blue << main_blue_shift;
/* store it in the array to be used later */
root_rgb[i] = red | green | blue;
}
}
X_UNLOCK;
}
......@@ -77,6 +116,8 @@ static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
static int db24 = 0;
static int xgetimage_8to24 = 1;
static double poll_8to24_delay = POLL_8TO24_DELAY;
static double cache_win = 0.0;
static int level2_8to24 = 0;
static int check_pointer_in_depth24(void) {
int tries = 0, in_24 = 0;
......@@ -129,13 +170,19 @@ static void parse_cmap8to24(void) {
db24 = 0;
xgetimage_8to24 = 1;
poll_8to24_delay = POLL_8TO24_DELAY;
level2_8to24 = 0;
cache_win = 0.0;
while (p) {
if (strstr(p, "dbg=") == p) {
db24 = atoi(p + strlen("dbg="));
} else if (strstr(p, "poll=") == p) {
poll_8to24_delay = atof(p + strlen("poll="));
} else if (strstr(p, "cachewin=") == p) {
cache_win = atof(p + strlen("cachewin="));
} else if (!strcmp(p, "nogetimage")) {
xgetimage_8to24 = 0;
} else if (!strcmp(p, "level2")) {
level2_8to24 = 1;
}
p = strtok(NULL, ",");
}
......@@ -175,6 +222,11 @@ static void set_poll_fb(void) {
pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h);
}
int MV_glob = 0;
int MV_count;
int MV_hit;
double MV_start;
void check_for_multivis(void) {
XWindowAttributes attr;
int doall = 0;
......@@ -190,8 +242,9 @@ void check_for_multivis(void) {
static double last_call = 0.0;
static double last_query = 0.0;
double now = dnow();
double delay;
if (now > last_parse + 0.75) {
if (now > last_parse + 1.0) {
last_parse = now;
parse_cmap8to24();
}
......@@ -207,6 +260,7 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
windows_8bpp[i].clip_region = NULL;
}
set_poll_fb();
......@@ -215,6 +269,10 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
doall = 1; /* fetch everything first time */
}
if (wireframe_in_progress) {
return;
}
set_root_cmap();
/*
......@@ -243,7 +301,13 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
}
/* snapshot + update the current stacking order: */
if (doall || now > last_update + 0.15) {
/* TUNABLE */
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay = 3.0 * poll_8to24_delay;
} else {
delay = 3.0 * POLL_8TO24_DELAY; /* 0.15 */
}
if (doall || now > last_update + delay) {
snapshot_stack_list(0, 0.0);
update_stack_list();
last_update = now;
......@@ -282,22 +346,41 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
}
}
X_UNLOCK;
}
MV_count = 0;
MV_hit = 0;
MV_start = dnow();
set_root_cmap();
/* loop over all toplevels, both 8 and 24 depths: */
X_LOCK; /* a giant lock around the whole activity */
for (k=0; k < stack_list_num; k++) {
Window r, parent;
Window *list0;
Status rc;
unsigned int nc0;
int i1;
XErrorHandler old_handler;
double delay;
Window win = stack_list[k].win;
if (now < last_query + 0.05) {
/* TUNABLE */
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay = 1.5 * poll_8to24_delay;
} else {
delay = 1.5 * POLL_8TO24_DELAY; /* 0.075 */
}
if (now < last_query + delay) {
break;
}
......@@ -328,12 +411,17 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
}
/* we recurse up to two levels down from stack_list windows */
X_LOCK;
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list0, &nc0);
X_UNLOCK;
if (! rc) {
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
trapped_xerror = 0;
continue;
}
trapped_xerror = 0;
/* loop over grandchildren of rootwin: */
for (i1=0; i1 < (int) nc0; i1++) {
......@@ -345,12 +433,22 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
if (check_depth(win1, win, doall)) {
continue;
}
X_LOCK;
if (level2_8to24) {
continue;
}
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win1, &r, &parent, &list1, &nc1);
X_UNLOCK;
if (! rc) {
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
trapped_xerror = 0;
continue;
}
trapped_xerror = 0;
/* loop over great-grandchildren of rootwin: */
for (i2=0; i2< (int) nc1; i2++) {
Window win2 = list1[i2];
......@@ -361,19 +459,20 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
/* more? Which wm does this? */
}
if (nc1) {
X_LOCK;
XFree(list1);
X_UNLOCK;
}
}
if (nc0) {
X_LOCK;
XFree(list0);
X_UNLOCK;
}
}
X_UNLOCK;
last_query = dnow();
MV_glob += MV_count;
if (0) fprintf(stderr, "MV_count: %d hit: %d %.4f %10.2f\n", MV_count, MV_hit, last_query - MV_start, MV_glob / (last_query - x11vnc_start));
if (screen_fixup_8 > 0.0 && now > last_fixup + screen_fixup_8) {
last_fixup = now;
mark_8bpp(MARK_8BPP_ALL);
......@@ -416,44 +515,124 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
}
}
}
if (0) fprintf(stderr, "done: %.4f\n", dnow() - last_query);
}
#define VW_CACHE_MAX 1024
static XWindowAttributes vw_cache_attr[VW_CACHE_MAX];
static Window vw_cache_win[VW_CACHE_MAX];
static void set_attr(XWindowAttributes *attr, int j) {
memcpy((void *) (vw_cache_attr+j), (void *) attr,
sizeof(XWindowAttributes));
}
#if 0
static int get_attr(XWindowAttributes *attr, int j) {
memcpy((void *) attr, (void *) (vw_cache_attr+j),
sizeof(XWindowAttributes));
return 1;
}
#endif
static XWindowAttributes wattr;
static XWindowAttributes *vw_lookup(Window win) {
static double last_purge = 0.0;
double now;
int i, j, k;
if (win == None) {
return NULL;
}
now = dnow();
if (now > last_purge + cache_win) {
last_purge = now;
for (i=0; i<VW_CACHE_MAX; i++) {
vw_cache_win[i] = None;
}
}
j = -1;
k = -1;
for (i=0; i<VW_CACHE_MAX; i++) {
if (vw_cache_win[i] == win) {
j = i;
break;
} else if (vw_cache_win[i] == None) {
k = i;
break;
}
}
if (j >= 0) {
MV_hit++;
return vw_cache_attr+j;
} else if (k >= 0) {
XWindowAttributes attr2;
int rc = valid_window(win, &attr2, 1);
if (rc) {
vw_cache_win[k] = win;
set_attr(&attr2, k);
return vw_cache_attr+k;
} else {
return NULL;
}
} else {
/* Full */
int rc = valid_window(win, &wattr, 1);
if (rc) {
return &wattr;
} else {
return NULL;
}
}
}
static int check_depth(Window win, Window top, int doall) {
XWindowAttributes attr;
XWindowAttributes attr, *pattr;
X_LOCK;
/* first see if it is (still) a valid window: */
if (! valid_window(win, &attr, 1)) {
X_UNLOCK;
return 1; /* indicate done */
MV_count++;
if (cache_win > 0.0) {
pattr = vw_lookup(win);
if (pattr == NULL) {
return 1; /* indicate done */
}
} else {
if (! valid_window(win, &attr, 1)) {
return 1; /* indicate done */
}
pattr = &attr;
}
X_UNLOCK;
if (! doall && attr.map_state != IsViewable) {
if (! doall && pattr->map_state != IsViewable) {
/*
* store results anyway... this may lead to table
* filling up, but currently this allows us to update
* state of onetime mapped windows.
*/
check_depth_win(win, top, attr);
check_depth_win(win, top, pattr);
return 1; /* indicate done */
} else if (check_depth_win(win, top, attr)) {
} else if (check_depth_win(win, top, pattr)) {
return 1; /* indicate done */
} else {
return 0; /* indicate not done */
}
}
static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
static int check_depth_win(Window win, Window top, XWindowAttributes *attr) {
int store_it = 0;
/*
* only store windows with depth not equal to the default visual's
* depth note some windows can have depth == 0 ... (skip them).
*/
if (attr.depth > 0) {
set_root_cmap();
if (depth == 24 && attr.depth != 24) {
if (attr->depth > 0) {
if (depth == 24 && attr->depth != 24) {
store_it = 1;
} else if (depth == 8 && root_cmap && attr.colormap !=
} else if (depth == 8 && root_cmap && attr->colormap !=
root_cmap) {
store_it = 1;
}
......@@ -462,13 +641,13 @@ static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
if (store_it) {
int i, j = -1, none = -1, nomap = -1;
int new = 0;
if (attr.map_state == IsViewable) {
if (attr->map_state == IsViewable) {
/* count the visible ones: */
multivis_count++;
if (attr.depth == 24) {
if (attr->depth == 24) {
multivis_24count++;
}
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr->depth);
}
/* try to find a table slot for this window: */
......@@ -489,7 +668,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
}
}
if (j < 0) {
if (attr.map_state != IsViewable) {
if (attr->map_state != IsViewable) {
/* no slot and not visible: not worth keeping */
return 1;
} else if (none >= 0) {
......@@ -503,7 +682,7 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr.depth);
/* otherwise we cannot store it... */
}
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d\n", win, attr.map_state, j, none, nomap, attr.depth);
if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d\n", win, attr->map_state, j, none, nomap, attr->depth);
/* store if if we found a slot j: */
if (j >= 0) {
......@@ -511,33 +690,34 @@ if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d
int x, y;
int now_vis = 0;
if (attr.map_state == IsViewable &&
if (attr->map_state == IsViewable &&
windows_8bpp[j].map_state != IsViewable) {
now_vis = 1;
}
if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", win, j, attr.map_state, attr.depth);
if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", win, j, attr->map_state, attr->depth);
windows_8bpp[j].win = win;
windows_8bpp[j].top = top;
windows_8bpp[j].depth = attr.depth;
windows_8bpp[j].map_state = attr.map_state;
windows_8bpp[j].cmap = attr.colormap;
windows_8bpp[j].map_installed = attr.map_installed;
windows_8bpp[j].w = attr.width;
windows_8bpp[j].h = attr.height;
windows_8bpp[j].depth = attr->depth;
windows_8bpp[j].map_state = attr->map_state;
windows_8bpp[j].cmap = attr->colormap;
windows_8bpp[j].map_installed = attr->map_installed;
windows_8bpp[j].w = attr->width;
windows_8bpp[j].h = attr->height;
windows_8bpp[j].fetched = 1;
windows_8bpp[j].last_fetched = dnow();
/* translate x y to be WRT the root window (not parent) */
X_LOCK;
xtranslate(win, window, 0, 0, &x, &y, &w, 1);
X_UNLOCK;
windows_8bpp[j].x = x;
windows_8bpp[j].y = y;
if (new || now_vis) {
if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, new, now_vis);
/* mark it immediately if a new one: */
mark_rect_as_modified(x, y, x + attr.width,
y + attr.height, 0);
X_UNLOCK; /* dont forget the giant lock */
mark_rect_as_modified(x, y, x + attr->width,
y + attr->height, 0);
X_LOCK;
}
} else {
/*
......@@ -583,10 +763,14 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
static int xi8_w = 0, xi24_w = 0;
XErrorHandler old_handler = NULL;
XWindowAttributes attr;
XImage *xi;
Window c, win = windows_8bpp[n].win;
static XWindowAttributes attr;
static Window last_win = None;
static double last_time = 0.0;
double now;
sraRegionPtr rect;
int mx1, mx2, my1, my2;
int ns = NSCAN/2;
......@@ -602,9 +786,17 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
}
X_LOCK;
if (! valid_window(windows_8bpp[n].win, &attr, 1)) {
X_UNLOCK;
return 0;
now = dnow();
if (last_win != None && win == last_win && now < last_time + 0.5) {
; /* use previous attr */
} else {
if (! valid_window(win, &attr, 1)) {
X_UNLOCK;
last_win = None;
return 0;
}
last_time = now;
last_win = win;
}
if (attr.depth != 8 && attr.depth != 24) {
......@@ -624,19 +816,25 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
n_off = poll24_fb_w * y1 + x1;
}
xtranslate(win, window, 0, 0, &xo, &yo, &c, 1);
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
/* xtranslate() not used to save two XSetErrorHandler calls */
XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
xo = x1 - xo;
yo = y1 - yo;
w = x2 - x1;
if (xo < 0 || yo < 0 || xo + w > attr.width) {
if (trapped_xerror || xo < 0 || yo < 0 || xo + w > attr.width) {
if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
XSetErrorHandler(old_handler);
trapped_xerror = 0;
X_UNLOCK;
return 0;
}
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
0, 0);
XSetErrorHandler(old_handler);
......@@ -943,6 +1141,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w,
windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
windows_8bpp[i].last_fetched = -1.0;
continue;
}
X_UNLOCK;
......@@ -954,6 +1153,7 @@ if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w,
windows_8bpp[i].w = attr.width;
windows_8bpp[i].h = attr.height;
windows_8bpp[i].fetched = 1;
windows_8bpp[i].last_fetched = dnow();
if (attr.map_state != IsViewable) {
continue;
......@@ -1053,7 +1253,6 @@ if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, s
return mapcount;
}
#define NCOLOR 256
static XColor color[CMAPMAX][NCOLOR];
static unsigned int rgb[CMAPMAX][NCOLOR];
static int cmap_failed[CMAPMAX];
......@@ -1188,19 +1387,26 @@ if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
sraRgnDestroy(clip);
}
static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth) {
static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
XWindowAttributes attr;
char *d;
if (xi) {
XDestroyImage(xi);
}
if (win_depth == 8) {
if (! valid_window(win, &attr, 1)) {
return (XImage *) NULL;
}
if (attr.depth != win_depth) {
return (XImage *) NULL;
} else if (win_depth == 8) {
d = (char *) malloc(dpy_x * dpy_y * 1);
} else if (win_depth == 24) {
d = (char *) malloc(dpy_x * dpy_y * 4);
} else {
return (XImage *) NULL;
}
return XCreateImage(dpy, visual, win_depth, ZPixmap, 0, d, dpy_x,
return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x,
dpy_y, 8, 0);
}
......@@ -1214,7 +1420,7 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
int poll_Bpl;
int do_getimage = xgetimage_8to24;
int line, n_off, j, h, w, vw;
int line, n_off, j, h, w;
unsigned int hi, idx;
XWindowAttributes attr;
XErrorHandler old_handler = NULL;
......@@ -1232,6 +1438,7 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
do_getimage = 1;
}
#if 0
if (do_getimage) {
X_LOCK;
vw = valid_window(win, &attr, 1);
......@@ -1239,6 +1446,9 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
}
if (do_getimage && vw) {
#else
if (do_getimage) {
#endif
static XImage *xi_8 = NULL;
static XImage *xi_24 = NULL;
XImage *xi = NULL, *xi_r;
......@@ -1250,37 +1460,43 @@ if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rec
hu = (unsigned int) h;
X_LOCK;
xtranslate(win, window, 0, 0, &xo, &yo, &c, 1);
xo = rect.x1 - xo;
yo = rect.y1 - yo;
if (db24 > 1) fprintf(stderr, "xywh: %d %d %d %d vs. %d %d\n", xo, yo, w, h, attr.width, attr.height);
if (xo < 0 || yo < 0 || w > attr.width || h > attr.height) {
X_UNLOCK;
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
return;
}
#define GETSUBIMAGE
#ifdef GETSUBIMAGE
if (win_depth == 8) {
if (xi_8 == NULL || xi_8->width != dpy_x ||
xi_8->height != dpy_y) {
xi_8 = cmap_xi(xi_8, attr.visual, attr.depth);
xi_8 = cmap_xi(xi_8, win, 8);
}
xi = xi_8;
} else if (win_depth == 24) {
if (xi_24 == NULL || xi_24->width != dpy_x ||
xi_24->height != dpy_y) {
xi_24 = cmap_xi(xi_24, attr.visual, attr.depth);
xi_24 = cmap_xi(xi_24, win, 24);
}
xi = xi_24;
}
#endif
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
xo = rect.x1 - xo;
yo = rect.y1 - yo;
if (db24 > 1) fprintf(stderr, "xywh: %d %d %d %d vs. %d %d\n", xo, yo, w, h, attr.width, attr.height);
if (trapped_xerror || xo < 0 || yo < 0) {
/* w > attr.width || h > attr.height */
XSetErrorHandler(old_handler);
X_UNLOCK;
trapped_xerror = 0;
if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
return;
}
trapped_xerror = 0;
#ifndef GETSUBIMAGE
xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
xi_r = xi;
......@@ -1427,15 +1643,15 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
static int last_map_count = 0, call_count = 0;
static double last_get_8bpp_validate = 0.0;
static double last_snapshot = 0.0;
double now, dt, d0;
double now;
double dt, d0 = 0.0, t2;
if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */
return;
}
now = dnow();
if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now - last_get_8bpp_validate);
if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dnow() - last_get_8bpp_validate);
call_count++;
......@@ -1453,10 +1669,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
return;
}
X_LOCK;
XFlush(dpy); /* make sure X server is up to date WRT input, etc */
X_UNLOCK;
/* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
h = y2 - y1;
......@@ -1465,7 +1677,6 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
if (depth == 8) {
/* need to cook up to depth 24 TrueColor */
/* pixelsize = 1 */
int tcm = CMAPMAX - 1;
n_off = main_bytes_per_line * y1 + pixelsize * x1;
......@@ -1473,7 +1684,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
dst = cmap8to24_fb + 4 * n_off;
set_root_cmap();
if (get_cmap(tcm, root_cmap)) {
if (root_cmap) {
int ps1 = 1, ps2 = 4;
#if 0
unsigned int hi;
......@@ -1496,7 +1707,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now
} else {
}
#endif
*ui = rgb[tcm][idx];
*ui = root_rgb[idx];
if (db24 > 2) histo[idx]++;
}
src += main_bytes_per_line;
......@@ -1534,21 +1745,36 @@ if (db24 > 2) histo[idx]++;
if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
now = dnow();
dt = now - last_get_8bpp_validate;
d0 = dnow();
if (dt < 0.0025) {
/* TUNABLES */
if (dt < 0.003) {
; /* XXX does this still give painting errors? */
} else {
int snapit = 0;
if (dt < 0.04) {
double delay1, delay2, delay3;
if (poll_8to24_delay >= POLL_8TO24_DELAY) {
delay1 = 1.0 * poll_8to24_delay;
delay2 = 2.0 * poll_8to24_delay;
delay3 = 10. * poll_8to24_delay;
} else {
delay1 = 1.0 * POLL_8TO24_DELAY; /* 0.05 */
delay2 = 2.0 * POLL_8TO24_DELAY; /* 0.1 */
delay3 = 10. * POLL_8TO24_DELAY; /* 0.5 */
}
if (cache_win > 1.0) {
delay2 *= 2;
delay3 *= 2;
}
if (dt < delay1) {
validate = 0;
}
if (last_map_count) {
if (now > last_snapshot + 0.05) {
if (now > last_snapshot + delay2) {
snapit = 1;
}
} else {
if (now > last_snapshot + 0.4) {
if (now > last_snapshot + delay3) {
snapit = 1;
}
}
......@@ -1556,15 +1782,20 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
if (snapit) {
/* less problems if we update the stack frequently */
snapshot_stack_list(0, 0.0);
if (0) fprintf(stderr, "SNAP time: %.4f\n", dnow() - now);
update_stack_list();
last_snapshot = now;
last_snapshot = dnow();
if (0) fprintf(stderr, "UPDA time: %.4f\n", last_snapshot - now);
}
if (0) t2 = dnow();
last_map_count = get_8bpp_regions(validate);
if (validate) {
last_get_8bpp_validate = now;
last_get_8bpp_validate = dnow();
}
if (0) fprintf(stderr, "get8bpp-%d: %.4f\n", validate, dnow() - t2);
}
if (db24) d0 = dnow();
if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p ncmaps=%d\n", w, h, main_fb, cmap8to24_fb, rfb_fb, ncmaps);
......@@ -1630,6 +1861,7 @@ if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0);
sraRgnDestroy(rect);
}
}
if (0) fprintf(stderr, "done time: %.4f\n", dnow() - d0);
if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}}
}
......
2006-02-06 Karl Runge <runge@karlrunge.com>
* x11vnc: -8to24 more speedups; tunables for very slow machines.
2006-02-04 Karl Runge <runge@karlrunge.com>
* x11vnc: -8to24 speedups and improvements.
......
x11vnc README file Date: Sat Feb 4 22:21:00 EST 2006
x11vnc README file Date: Mon Feb 6 00:16:18 EST 2006
The following information is taken from these URLs:
......@@ -4898,7 +4898,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions)
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-04
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-06
x11vnc options:
-display disp -auth file
......@@ -5009,7 +5009,7 @@ libvncserver-tight-extension options:
% x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-04
x11vnc: allow VNC connections to real X11 displays. 0.8 lastmod: 2006-02-06
Typical usage is:
......@@ -5201,6 +5201,18 @@ Options:
"poll=t" where "t" is a floating point time.
(default: 0.05)
Setting the option "level2" will limit the search
for non-default visual windows to two levels from the
root window. Do this on slow machines where you know
the window manager only imposes one extra window between
the app window and the root window.
Also for very slow machines use "cachewin=t"
where t is a floating point amount of time to cache
XGetWindowAttributes results. E.g. cachewin=5.0.
This may lead to the windows being unnoticed for this
amount of time when deiconifying, painting errors, etc.
Debugging for this mode can be enabled by setting
"dbg=1", "dbg=2", or "dbg=3".
......
......@@ -209,6 +209,18 @@ void print_help(int mode) {
" \"poll=t\" where \"t\" is a floating point time.\n"
" (default: %.2f)\n"
"\n"
" Setting the option \"level2\" will limit the search\n"
" for non-default visual windows to two levels from the\n"
" root window. Do this on slow machines where you know\n"
" the window manager only imposes one extra window between\n"
" the app window and the root window.\n"
"\n"
" Also for very slow machines use \"cachewin=t\"\n"
" where t is a floating point amount of time to cache\n"
" XGetWindowAttributes results. E.g. cachewin=5.0.\n"
" This may lead to the windows being unnoticed for this\n"
" amount of time when deiconifying, painting errors, etc.\n"
"\n"
" Debugging for this mode can be enabled by setting \n"
" \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n"
"\n"
......
......@@ -25,15 +25,25 @@ Window descend_pointer(int depth, Window start, char *name_info, int len);
Window parent_window(Window win, char **name) {
Window r, parent;
Window *list;
XErrorHandler old_handler;
unsigned int nchild;
int rc;
if (name != NULL) {
*name = NULL;
}
if (! XQueryTree(dpy, win, &r, &parent, &list, &nchild)) {
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list, &nchild);
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
trapped_xerror = 0;
return None;
}
trapped_xerror = 0;
if (list) {
XFree(list);
}
......@@ -59,8 +69,8 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
return 0;
}
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
if (XGetWindowAttributes(dpy, win, pattr)) {
ok = 1;
}
......@@ -148,6 +158,7 @@ void snapshot_stack_list(int free_only, double allowed_age) {
last_free = now;
X_LOCK;
/* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
num = (int) ui;
......
......@@ -2,7 +2,7 @@
.TH X11VNC "1" "February 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8, lastmod: 2006-02-04
version: 0.8, lastmod: 2006-02-06
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -241,6 +241,18 @@ non-default visual regions for changes, use the option
"poll=t" where "t" is a floating point time.
(default: 0.05)
.IP
Setting the option "level2" will limit the search
for non-default visual windows to two levels from the
root window. Do this on slow machines where you know
the window manager only imposes one extra window between
the app window and the root window.
.IP
Also for very slow machines use "cachewin=t"
where t is a floating point amount of time to cache
XGetWindowAttributes results. E.g. cachewin=5.0.
This may lead to the windows being unnoticed for this
amount of time when deiconifying, painting errors, etc.
.IP
Debugging for this mode can be enabled by setting
"dbg=1", "dbg=2", or "dbg=3".
.PP
......
......@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8 lastmod: 2006-02-04";
char lastmod[] = "0.8 lastmod: 2006-02-06";
/* X display info */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment