changes to ncache cache aging and xdamage skipping

pull/1/head
runge 18 years ago
parent 76a495aff1
commit 5b607a4449

@ -1,5 +1,5 @@
x11vnc README file Date: Wed Jan 3 19:10:56 EST 2007 x11vnc README file Date: Sun Jan 7 12:08:49 EST 2007
The following information is taken from these URLs: The following information is taken from these URLs:
@ -4171,6 +4171,52 @@ ied)
(rare problem). (rare problem).
Example for the KDE desktop:
Launch the "KDE Control Center" utility. Sometimes this is called
"Personal Settings".
Select "Desktop".
Then Select "Window Behavior". In the "Moving" Tab set these:
* YES - Display content in moving windows
* YES - Display content in resizing windows
* NO - Display window geometry when moving or resizing
* NO - Animate minimize and restore
In the "Translucency" Tab set:
* NO - Use translucency/shadows
Next hit "Back" and then select "Panels".
In the "Appearance" Tab set:
* NO - Enable icon mouseover effects
* NO - Enable transparency
Now go all the way back up to the top and Select "Appearance &
Themes".
Select "Background" and set:
* YES - No picture
* Colors: Single Color
Select "Fonts" and disable anti-aliased fonts if you are bold enough.
Select "Launch Feedback" and set:
* Busy Cursor: No Busy Cursor
* NO - Enable taskbar notification
Select "Screen Saver" and set:
* Screen Saver: Blank Screen
Select "Style" and in the "Effects" Tab set:
* NO - Enable GUI effects
Example for the GNOME desktop:
* TBD.
Q-64: Does x11vnc support the X DAMAGE Xserver extension to find Q-64: Does x11vnc support the X DAMAGE Xserver extension to find
modified regions of the screen quickly and efficiently? modified regions of the screen quickly and efficiently?
@ -5436,7 +5482,8 @@ EndSection
"-nodpms" option to keep the Monitor out of low power state while VNC "-nodpms" option to keep the Monitor out of low power state while VNC
clients are connected. This is basically the same as typing "xset dpms clients are connected. This is basically the same as typing "xset dpms
force on" periodically. (if you don't want to do these things just force on" periodically. (if you don't want to do these things just
disable the screensaver). disable the screensaver). Feel free to file a bug against
kdesktop_lock with KDE.
Q-97: Can I use x11vnc to view my VMWare session remotely? Q-97: Can I use x11vnc to view my VMWare session remotely?
@ -9272,7 +9319,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options: Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions) % x11vnc -opts (see below for -help long descriptions)
x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-03 x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-07
x11vnc options: x11vnc options:
-display disp -auth file -id windowid -display disp -auth file -id windowid
@ -9379,7 +9426,7 @@ libvncserver-tight-extension options:
% x11vnc -help % x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-03 x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-07
(type "x11vnc -opts" to just list the options.) (type "x11vnc -opts" to just list the options.)

@ -195,7 +195,7 @@ int wireframe_in_progress = 0;
int wireframe_local = 1; int wireframe_local = 1;
#ifndef NCACHE #ifndef NCACHE
#define NCACHE -10 #define NCACHE -12
#endif #endif
#ifdef MACOSX #ifdef MACOSX
int ncache = 0; int ncache = 0;

@ -2040,7 +2040,9 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
} }
rfbReleaseClientIterator(i); rfbReleaseClientIterator(i);
fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d dt=%.4f\n", nrects, ncr, dnow() - start); last_copyrect = dnow();
fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d dt=%.4f %.4f\n", nrects, ncr, dnow() - start, dnowx());
} }
@ -4183,7 +4185,7 @@ fprintf(stderr, "--YES, wf_raise\n");
nb = &nr; nb = &nr;
} }
valid = 1; valid = 1;
bs_restore(idx, nb, &attr, 0, 1, &valid, 1); bs_restore(idx, nb, NULL, &attr, 0, 1, &valid, 1);
try_to_fix_su(orig_frame, idx, 0x1, nb, NULL); try_to_fix_su(orig_frame, idx, 0x1, nb, NULL);
if (nb && nr) { if (nb && nr) {
batch_push(nr, -1.0); batch_push(nr, -1.0);
@ -4690,7 +4692,7 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} }
if (doit) { if (doit) {
if (try_copyrect_drag) { if (try_copyrect_drag && ncache > 0) {
if (!ncache_copyrect) { if (!ncache_copyrect) {
do_copyrect_drag = 0; do_copyrect_drag = 0;
} else if (w != box_w || h != box_h) { } else if (w != box_w || h != box_h) {
@ -4722,7 +4724,9 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} }
if (do_copyrect_drag <= 0) { if (do_copyrect_drag <= 0) {
if (!drew_box && ncache_wf_raises) { if (ncache <= 0) {
;
} else if (!drew_box && ncache_wf_raises) {
Window fr = orig_frame; Window fr = orig_frame;
int idx = lookup_win_index(fr); int idx = lookup_win_index(fr);
if (idx < 0) { if (idx < 0) {
@ -5935,7 +5939,9 @@ int lookup_old_stack_index(int ic) {
cache_list[k].su_h = -1; \ cache_list[k].su_h = -1; \
cache_list[k].time = 0.0; \ cache_list[k].time = 0.0; \
cache_list[k].bs_time = 0.0; \ cache_list[k].bs_time = 0.0; \
cache_list[k].su_time = 0.0; cache_list[k].su_time = 0.0; \
cache_list[k].vis_obs_time = 0.0; \
cache_list[k].vis_unobs_time = 0.0;
#define DELETE(k) \ #define DELETE(k) \
if (0) fprintf(stderr, "DELETE(%d) = 0x%x\n", k, cache_list[k].win); \ if (0) fprintf(stderr, "DELETE(%d) = 0x%x\n", k, cache_list[k].win); \
@ -6234,10 +6240,41 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int
int do_expire = 1; int do_expire = 1;
int do_force = 1; int do_force = 1;
double now = dnow(), r; double now = dnow(), r;
double newest = -1.0, oldest = -1.0, basetime;
double map_factor = 0.25;
for (i=0; i<cache_list_num; i++) {
double d, d1, d2;
d1 = cache_list[i].bs_time;
d2 = cache_list[i].su_time;
d = d1;
if (d2 > d) d = d2;
if (d == 0.0) {
continue;
}
if (oldest == -1.0 || d < oldest) {
oldest = d;
}
if (newest == -1.0 || d > newest) {
newest = d;
}
}
if (newest == -1.0) {
newest = now;
}
if (oldest == -1.0) {
oldest = newest - 1800;
}
basetime = newest + 0.1 * (newest - oldest);
if (do_expire) { if (do_expire) {
int old[10], N = 4; int old[10], N = 4;
double dold[10], fa, d, d1, d2, d3; double dold[10], fa, d, d1, d2;
int a0 = w * h, a1; int a0 = w * h, a1;
for (k=1; k<=N; k++) { for (k=1; k<=N; k++) {
@ -6270,13 +6307,12 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int
if (k < 1) k = 1; if (k < 1) k = 1;
if (k > N) continue; if (k > N) continue;
d1 = cache_list[i].time; d1 = cache_list[i].bs_time;
d2 = cache_list[i].bs_time; d2 = cache_list[i].su_time;
d3 = cache_list[i].su_time;
d = d1; d = d1;
if (d2 > d) d = d2; if (d2 > d) d = d2;
if (d3 > d) d = d3; if (d == 0.0) d = oldest;
if (dold[k] == -1.0 || d < dold[k]) { if (dold[k] == -1.0 || d < dold[k]) {
old[k] = i; old[k] = i;
@ -6290,10 +6326,13 @@ void expire_rects2(int idx, int w, int h, int *x_hit, int *y_hit, int big1, int
int k_w = cache_list[ik].bs_w; int k_w = cache_list[ik].bs_w;
int k_h = cache_list[ik].bs_h; int k_h = cache_list[ik].bs_h;
wgt[nwgt] = (now - dold[k]) / (k_w * k_h); wgt[nwgt] = (basetime - dold[k]) / (k_w * k_h);
if (cache_list[ik].map_state == IsViewable) {
wgt[nwgt] *= map_factor;
}
type[nwgt] = Expire; type[nwgt] = Expire;
val[0][nwgt] = ik; val[0][nwgt] = ik;
fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], now - dold[k], k_w * k_h, w*h); fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], basetime - dold[k], k_w * k_h, w*h);
nwgt++; nwgt++;
if (nwgt >= nwgt_max) { if (nwgt >= nwgt_max) {
break; break;
@ -6319,8 +6358,8 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1
continue; continue;
} }
for (corner_y = 0; corner_y < 2; corner_y++) { for (corner_y = 0; corner_y < 2; corner_y++) {
double age = 0.0, area = 0.0, a; double age = 0.0, area = 0.0, amap = 0.0, a;
double d, d1, d2, d3, score; double d, d1, d2, score;
int nc = 0; int nc = 0;
x0 = 0; x0 = 0;
@ -6336,6 +6375,7 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1
r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h); r1 = sraRgnCreateRect(x0, y0, x0+w, y0+h);
for (i=0; i<cache_list_num; i++) { for (i=0; i<cache_list_num; i++) {
double top;
int xb = cache_list[i].bs_x; int xb = cache_list[i].bs_x;
int yb = cache_list[i].bs_y; int yb = cache_list[i].bs_y;
int wb = cache_list[i].bs_w; int wb = cache_list[i].bs_w;
@ -6357,23 +6397,28 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1
a = wb * hb; a = wb * hb;
d1 = cache_list[i].time; d1 = cache_list[i].bs_time;
d2 = cache_list[i].bs_time; d2 = cache_list[i].su_time;
d3 = cache_list[i].su_time;
d = d1; d = d1;
if (d2 > d) d = d2; if (d2 > d) d = d2;
if (d3 > d) d = d3; if (d == 0.0) d = oldest;
if (cache_list[i].map_state == IsViewable) {
amap += a;
}
area += a; area += a;
age += (now - d) * a; age += (basetime - d) * a;
nc++; nc++;
} }
if (nc == 0) { if (nc == 0) {
score = 999999.9; score = 999999.9;
} else { } else {
double fac;
age = age / area; age = age / area;
score = age / area; score = age / area;
fac = 1.0 * (1.0 - amap/area) + map_factor * (amap/area);
score *= fac;
} }
wgt[nwgt] = score; wgt[nwgt] = score;
@ -6381,7 +6426,7 @@ fprintf(stderr, "Expire[%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 1
val[0][nwgt] = n; val[0][nwgt] = n;
val[1][nwgt] = x0; val[1][nwgt] = x0;
val[2][nwgt] = y0; val[2][nwgt] = y0;
fprintf(stderr, "Force [%02d] %9.5f age=%9.4f area=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], age, (int) area, w*h); fprintf(stderr, "Force [%02d] %9.5f age=%9.4f area=%8d amap=%8d need=%8d\n", nwgt, 10000 * wgt[nwgt], age, (int) area, (int) amap, w*h);
nwgt++; nwgt++;
if (nwgt >= nwgt_max) break; if (nwgt >= nwgt_max) break;
sraRgnDestroy(r1); sraRgnDestroy(r1);
@ -6987,8 +7032,8 @@ if (verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
// if (!novalidate) { // if (!novalidate) {
// STORE(idx, win, attr); // STORE(idx, win, attr);
// } // }
cache_list[idx].bs_time = dnow(); last_bs_save = cache_list[idx].bs_time = dnow();
return 1; return 1;
} }
@ -7087,12 +7132,12 @@ if (verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
// if (!novalidate) { // if (!novalidate) {
// STORE(idx, win, attr); // STORE(idx, win, attr);
// } // }
cache_list[idx].su_time = dnow(); last_su_save = cache_list[idx].su_time = dnow();
return 1; return 1;
} }
int bs_restore(int idx, int *nbatch, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { int bs_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) {
Window win = cache_list[idx].win; Window win = cache_list[idx].win;
int x1, y1, w1, h1; int x1, y1, w1, h1;
int x2, y2, w2, h2; int x2, y2, w2, h2;
@ -7178,6 +7223,9 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
if (clip) { if (clip) {
clip_region(r, win); clip_region(r, win);
} }
if (rmask != NULL) {
sraRgnAnd(r, rmask);
}
dtA = dnowx(); dtA = dnowx();
if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
@ -7193,11 +7241,13 @@ if (verb) fprintf(stderr, "BS_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
// if (!novalidate) { // if (!novalidate) {
// STORE(idx, win, attr); // STORE(idx, win, attr);
// } // }
last_bs_restore = dnow();
return 1; return 1;
} }
int su_restore(int idx, int *nbatch, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) { int su_restore(int idx, int *nbatch, sraRegionPtr rmask, XWindowAttributes *attr, int clip, int nopad, int *valid, int verb) {
Window win = cache_list[idx].win; Window win = cache_list[idx].win;
int x1, y1, w1, h1; int x1, y1, w1, h1;
int x2, y2, w2, h2; int x2, y2, w2, h2;
@ -7285,6 +7335,9 @@ fprintf(stderr, "SU_rest: su_x/bs_x/su_time: %d %d %.3f\n", x, cache_list[idx].b
if (clip) { if (clip) {
clip_region(r, win); clip_region(r, win);
} }
if (rmask != NULL) {
sraRgnAnd(r, rmask);
}
dtA = dnowx(); dtA = dnowx();
if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
@ -7302,6 +7355,9 @@ if (verb) fprintf(stderr, "SU_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
// } else if (!novalidate) { // } else if (!novalidate) {
// STORE(idx, win, attr); // STORE(idx, win, attr);
// } // }
last_su_restore = dnow();
return 1; return 1;
} }
@ -7953,8 +8009,40 @@ if (type == UnmapNotify) w = Ev[n].xunmap.window;
if (type == MapNotify) w = Ev[n].xmap.window; if (type == MapNotify) w = Ev[n].xmap.window;
if (type == Expose) w = Ev[n].xexpose.window; if (type == Expose) w = Ev[n].xexpose.window;
if (type == ConfigureNotify) w = Ev[n].xconfigure.window; if (type == ConfigureNotify) w = Ev[n].xconfigure.window;
if (type == VisibilityNotify) w = win;
if (n == *n_in) fprintf(stderr, "\n"); if (n == *n_in) fprintf(stderr, "\n");
fprintf(stderr, "----- %d inputev 0x%08x w: 0x%08x %s\n", n, win, w, Etype(type)); if (1) {
char *msg = "";
int idx = -1, x = 0, y = 0, wd = 0, ht = 0;
if (w != None) {
idx = lookup_win_index(w);
if (idx >= 0) {
x = cache_list[idx].x;
y = cache_list[idx].y;
wd = cache_list[idx].width;
ht = cache_list[idx].height;
}
}
if (type == VisibilityNotify) {
msg = VState(Ev[n].xvisibility.state);
} else if (type == ConfigureNotify) {
int x_new = Ev[n].xconfigure.x;
int y_new = Ev[n].xconfigure.y;
int w_new = Ev[n].xconfigure.width;
int h_new = Ev[n].xconfigure.height;
if (idx >= 0) {
if (w_new != wd || h_new != ht) {
msg = "change size";
} else if (x_new != x || y_new != y) {
msg = "change position";
} else {
msg = "change stacking";
}
}
}
fprintf(stderr, "----- %d inputev 0x%08x w: 0x%08x %04dx%04d+%04d+%04d %s %s\n", n, win, w, wd, ht, x, y, Etype(type), msg);
}
if (win == rootwin) { if (win == rootwin) {
if (type == CreateNotify) { if (type == CreateNotify) {
@ -8038,191 +8126,15 @@ fprintf(stderr, "----- skip %s\n", Etype(type));
*n_in = n; *n_in = n;
} }
int check_ncache(int reset, int mode) { static int saw_desktop_change = 0;
static double last_root = 0.0;
static int first = 1;
static int last_client_count = -1;
int i, k, n;
int did_sched = 0;
double now, refresh = 60.0; void check_sched(int try_batch, int *did_sched) {
Window win, win2; static double last_root = 0.0;
double refresh = 60.0;
int i, k, valid;
Window win;
XWindowAttributes attr; XWindowAttributes attr;
int valid; double now = dnow();
int try_batch = 1; /* XXX Y */
int use_batch = 0;
int nreg = 0, *nbatch;
int create_cnt;
int pixels = 0, ttot;
int desktop_change = 0, n1, n2;
static int saw_desktop_change = 0;
int missed_su_restore = 0;
int missed_bs_restore = 0;
sraRegionPtr r0, r;
sraRegionPtr missed_su_restore_rgn;
sraRegionPtr missed_bs_restore_rgn;
int nrects = 0;
int nsave, nxsel;
int did_vis_snap = 0;
int skipwins_n = 0;
int skipwins_max = 256;
Window skipwins[256];
if (unixpw_in_progress) return -1;
#ifdef MACOSX
if (! macosx_console) {
RAWFB_RET(-1)
}
#else
RAWFB_RET(-1)
#endif
if (! screen) {
return -1;
}
now = dnow();
if (ncache0) {
if (reset) {
;
} else if (!client_count || !ncache || nofb) {
static double last_purge = 0.0;
double delay = client_count ? 0.5 : 2.0;
if (now > last_purge + delay) {
int c = 0;
XEvent ev;
X_LOCK;
while (xcheckmaskevent(dpy, all_ev, &ev)) {
c++;
}
X_UNLOCK;
last_purge = dnow();
if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
}
if (!client_count && last_client_count >= 0 &&
client_count != last_client_count) {
/* this should use less RAM when no clients */
do_new_fb(1);
}
last_client_count = client_count;
return -1;
}
}
last_client_count = client_count;
if (ncache && ! ncache0) {
ncache0 = ncache;
}
if (! ncache || ! ncache0) {
return -1;
}
if (subwin) {
return -1;
}
if (nofb) {
return -1;
}
if (reset) {
rfbLog("check_ncache: resetting cache\n");
for (i=0; i < cache_list_num; i++) {
free_rect(i);
CLEAR(i);
}
for (n = 1; n <= ncache; n++) {
if (rect_reg[n] != NULL) {
sraRgnDestroy(rect_reg[n]);
rect_reg[n] = NULL;
}
}
zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y);
mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0);
snap_old();
return -1;
}
if (first) {
int dx = 10, dy = 24, ds = 0;
int Dx = dpy_x, Dy = dpy_y;
first = 0;
for (i=0; i < NRECENT; i++) {
recent[i] = None;
}
for (i=0; i < NSCHED; i++) {
sched_bs[i] = None;
}
rlast = 0;
X_LOCK;
/* event leak with client_count == 0 */
xselectinput_rootwin |= SubstructureNotifyMask;
XSelectInput_wr(dpy, rootwin, xselectinput_rootwin);
X_UNLOCK;
if (scaling) {
Dx = scaled_x;
Dy = scaled_y;
}
if (!rotating_same) {
int t = Dx;
Dx = Dy;
Dy = t;
}
for (i = 0; i < 3; i++) {
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+1*dy,
"This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy,
"Try resizing your VNC Viewer so you don't see it!! Pay no attention to the man behind the curtain...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy,
"To disable run the server with: x11vnc -ncache 0 ...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy,
"More info: http://www.karlrunge.com/x11vnc/#faq-client-caching",
white_pixel());
ds += 8 * dy;
}
snapshot_cache_list(0, 100.0);
for (i=0; i < cache_list_num; i++) {
CLEAR(i);
}
for (n = 1; n <= ncache; n++) {
rect_reg[n] = NULL;
}
snap_old();
}
if (now < last_client + 4) {
return -1;
}
if (hack_val == 2) {
block_stats();
hack_val = 1;
}
#ifdef MACOSX
if (macosx_console) {
static double last_all_windows = 0.0;
if (! macosx_checkevent(NULL)) {
if (now > last_all_windows + 0.05) {
macosxCGS_get_all_windows();
last_all_windows = dnow();
}
}
/* XXX Y */
rootwin = -1;
}
#endif
if (now > last_root + refresh) { if (now > last_root + refresh) {
@ -8265,8 +8177,6 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned
last_root = dnow(); last_root = dnow();
} }
check_zero_rects();
if (now > last_sched_bs + 0.30) { if (now > last_sched_bs + 0.30) {
static double last_sched_vis = 0.0; static double last_sched_vis = 0.0;
int nr = 0, *bat = NULL; int nr = 0, *bat = NULL;
@ -8329,7 +8239,7 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win);
} }
sched_bs[i] = None; sched_bs[i] = None;
} }
did_sched = 1; *did_sched = 1;
if (now > last_sched_vis + 3.0 && now > last_wireframe + 2.0) { if (now > last_sched_vis + 3.0 && now > last_wireframe + 2.0) {
static double last_vis = 0.0; static double last_vis = 0.0;
@ -8338,7 +8248,7 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win);
int diff, nv = 32, vis_now_n = 0; int diff, nv = 32, vis_now_n = 0;
Window win; Window win;
did_vis_snap = 1; if (1) fprintf(stderr, "VIS snapshot all %.4f\n", dnowx());
for (i=0; i < cache_list_num; i++) { for (i=0; i < cache_list_num; i++) {
int ok = 0; int ok = 0;
int top_only = 1; int top_only = 1;
@ -8400,6 +8310,9 @@ fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%x\n", i, win);
win = cache_list[i].win; win = cache_list[i].win;
valid = 0; valid = 0;
fprintf(stderr, "*VIS BS_save: 0x%x %d %d %d\n", win, cache_list[i].width, cache_list[i].height, cache_list[i].map_state); fprintf(stderr, "*VIS BS_save: 0x%x %d %d %d\n", win, cache_list[i].width, cache_list[i].height, cache_list[i].map_state);
if (now < cache_list[i].vis_unobs_time + 0.75 && now < cache_list[i].vis_obs_time + 0.75) {
continue;
}
bs_save(i, bat, &attr, !top_now[k], 0, &valid, 0); bs_save(i, bat, &attr, !top_now[k], 0, &valid, 0);
if (valid) { if (valid) {
STORE(i, win, attr); STORE(i, win, attr);
@ -8419,6 +8332,193 @@ fprintf(stderr, "*VIS BS_save: 0x%x %d %d %d\n", win, cache_list[i].width, cach
} }
last_sched_bs = dnow(); last_sched_bs = dnow();
} }
}
int check_ncache(int reset, int mode) {
static int first = 1;
static int last_client_count = -1;
int i, k, n;
int did_sched = 0;
Window win, win2;
XWindowAttributes attr;
int valid;
int try_batch = 1; /* XXX Y */
int use_batch = 0;
int nreg = 0, *nbatch;
int create_cnt;
int pixels = 0, ttot;
int desktop_change = 0, n1, n2;
int missed_su_restore = 0;
int missed_bs_restore = 0;
sraRegionPtr r0, r;
sraRegionPtr missed_su_restore_rgn;
sraRegionPtr missed_bs_restore_rgn;
sraRegionPtr unmapped_rgn;
int nrects = 0;
int nsave, nxsel;
double now;
int skipwins_n = 0;
int skipwins_max = 256;
Window skipwins[256];
if (unixpw_in_progress) return -1;
#ifdef MACOSX
if (! macosx_console) {
RAWFB_RET(-1)
}
#else
RAWFB_RET(-1)
#endif
if (! screen) {
return -1;
}
now = dnow();
if (ncache0) {
if (reset) {
;
} else if (!client_count || !ncache || nofb) {
static double last_purge = 0.0;
double delay = client_count ? 0.5 : 2.0;
if (now > last_purge + delay) {
int c = 0;
XEvent ev;
X_LOCK;
while (xcheckmaskevent(dpy, all_ev, &ev)) {
c++;
}
X_UNLOCK;
last_purge = dnow();
if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
}
if (!client_count && last_client_count >= 0 &&
client_count != last_client_count) {
/* this should use less RAM when no clients */
do_new_fb(1);
}
last_client_count = client_count;
return -1;
}
}
last_client_count = client_count;
if (ncache && ! ncache0) {
ncache0 = ncache;
}
if (! ncache || ! ncache0) {
return -1;
}
if (subwin) {
return -1;
}
if (nofb) {
return -1;
}
if (reset) {
rfbLog("check_ncache: resetting cache\n");
for (i=0; i < cache_list_num; i++) {
free_rect(i);
CLEAR(i);
}
for (n = 1; n <= ncache; n++) {
if (rect_reg[n] != NULL) {
sraRgnDestroy(rect_reg[n]);
rect_reg[n] = NULL;
}
}
zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y);
mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0);
snap_old();
return -1;
}
if (first) {
int dx = 10, dy = 24, ds = 0;
int Dx = dpy_x, Dy = dpy_y;
first = 0;
for (i=0; i < NRECENT; i++) {
recent[i] = None;
}
for (i=0; i < NSCHED; i++) {
sched_bs[i] = None;
}
rlast = 0;
X_LOCK;
/* event leak with client_count == 0 */
xselectinput_rootwin |= SubstructureNotifyMask;
XSelectInput_wr(dpy, rootwin, xselectinput_rootwin);
X_UNLOCK;
if (scaling) {
Dx = scaled_x;
Dy = scaled_y;
}
if (!rotating_same) {
int t = Dx;
Dx = Dy;
Dy = t;
}
for (i = 0; i < 3; i++) {
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+1*dy,
"This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy,
"Try resizing your VNC Viewer so you don't see it!! Pay no attention to the man behind the curtain...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy,
"To disable run the server with: x11vnc -ncache 0 ...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy,
"More info: http://www.karlrunge.com/x11vnc/#faq-client-caching",
white_pixel());
ds += 8 * dy;
}
snapshot_cache_list(0, 100.0);
for (i=0; i < cache_list_num; i++) {
CLEAR(i);
}
for (n = 1; n <= ncache; n++) {
rect_reg[n] = NULL;
}
snap_old();
}
check_zero_rects();
if (now < last_client + 4) {
return -1;
}
if (hack_val == 2) {
block_stats();
hack_val = 1;
}
#ifdef MACOSX
if (macosx_console) {
static double last_all_windows = 0.0;
if (! macosx_checkevent(NULL)) {
if (now > last_all_windows + 0.05) {
macosxCGS_get_all_windows();
last_all_windows = dnow();
}
}
/* XXX Y */
rootwin = -1;
}
#endif
n = 0; n = 0;
ttot = 0; ttot = 0;
@ -8506,10 +8606,10 @@ fprintf(stderr, "PRELOOP: RepartNotify: 0x%x %d idx=%d\n", win2, n1, idx);
} }
if (n == 0) { if (n == 0) {
check_sched(try_batch, &did_sched);
return 0; return 0;
} }
fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events. %.4f\n", n, now - x11vnc_start); fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events. %.4f\n", n, now - x11vnc_start);
if (did_vis_snap) fprintf(stderr, "VIS snapshot all %.4f\n", dnowx());
if (try_batch) { if (try_batch) {
use_batch = 1; use_batch = 1;
@ -8663,6 +8763,7 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%x %d\n", twin, n2);
missed_su_restore_rgn = sraRgnCreate(); missed_su_restore_rgn = sraRgnCreate();
missed_bs_restore_rgn = sraRgnCreate(); missed_bs_restore_rgn = sraRgnCreate();
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
unmapped_rgn = sraRgnCreate();
for (k = 0; k < skipwins_n; k++) { for (k = 0; k < skipwins_n; k++) {
fprintf(stderr, "skipwins[%d] 0x%x\n", k, skipwins[k]); fprintf(stderr, "skipwins[%d] 0x%x\n", k, skipwins[k]);
@ -8771,12 +8872,12 @@ fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x %
if (x_old != x_new || y_old != y_new) { if (x_old != x_new || y_old != y_new) {
/* invalidate su */ /* invalidate su */
cache_list[idx].su_time = 0.0; cache_list[idx].su_time = 0.0;
fprintf(stderr, " INVALIDATE su: 0x%x xy: %d/%d %d/%d \n", (unsigned int) win, x_old, y_old, x_new, y_new); fprintf(stderr, " INVALIDATE su: 0x%x xy: +%d+%d +%d+%d \n", (unsigned int) win, x_old, y_old, x_new, y_new);
} }
if (w_old != w_new || h_old != h_new) { if (w_old != w_new || h_old != h_new) {
/* invalidate bs */ /* invalidate bs */
cache_list[idx].bs_time = 0.0; cache_list[idx].bs_time = 0.0;
fprintf(stderr, " INVALIDATE bs: 0x%x wh: %d/%d %d/%d \n", (unsigned int) win, w_old, h_old, w_new, h_new); fprintf(stderr, " INVALIDATE bs: 0x%x wh: %dx%d %dx%d \n", (unsigned int) win, w_old, h_old, w_new, h_new);
} }
stack_change = 0; stack_change = 0;
@ -8831,9 +8932,26 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
ok = 0; ok = 0;
} }
if (ok) { if (ok) {
int x2, y2, w2, h2;
sraRegionPtr rmask = NULL;
X_UNLOCK; X_UNLOCK;
valid = 0; valid = 0;
bs_restore(idx, nbatch, &attr, 0, 1, &valid, 1); if (dnow() < cache_list[idx].vis_unobs_time + 3.00 && !sraRgnEmpty(unmapped_rgn)) {
x2 = cache_list[idx].x;
y2 = cache_list[idx].y;
w2 = cache_list[idx].width;
h2 = cache_list[idx].height;
rmask = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(rmask, unmapped_rgn);
if (sraRgnEmpty(rmask)) {
sraRgnDestroy(rmask);
rmask = NULL;
}
}
bs_restore(idx, nbatch, rmask, &attr, 0, 1, &valid, 1);
if (rmask != NULL) {
sraRgnDestroy(rmask);
}
X_LOCK; X_LOCK;
if (valid) { if (valid) {
STORE(idx, win, attr); STORE(idx, win, attr);
@ -8852,6 +8970,11 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
} }
} }
} }
if (state == VisibilityUnobscured) {
cache_list[idx].vis_unobs_time = dnow();
} else if (cache_list[idx].vis_state == VisibilityUnobscured) {
cache_list[idx].vis_obs_time = dnow();
}
cache_list[idx].vis_state = state; cache_list[idx].vis_state = state;
} else if (type == MapNotify) { } else if (type == MapNotify) {
@ -8900,7 +9023,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", ik, (unsigned int) win
} }
} }
valid = 0; valid = 0;
if (bs_restore(idx, nbatch, &attr, 0, 0, &valid, 1)) { /* XXX clip? */ if (bs_restore(idx, nbatch, NULL, &attr, 0, 0, &valid, 1)) { /* XXX clip? */
; ;
} else { } else {
idx_add_rgn(missed_bs_restore_rgn, r0, idx); idx_add_rgn(missed_bs_restore_rgn, r0, idx);
@ -8941,6 +9064,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", ik, (unsigned int) win
cache_list[idx].map_state = IsViewable; cache_list[idx].map_state = IsViewable;
} else if (type == UnmapNotify) { } else if (type == UnmapNotify) {
int x2, y2, w2, h2;
idx = lookup_win_index(win); idx = lookup_win_index(win);
fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win, idx); fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win, idx);
@ -8984,7 +9108,7 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win
bs_save(idx, nbatch, &attr, 1, 0, &valid, 1); bs_save(idx, nbatch, &attr, 1, 0, &valid, 1);
} }
valid = 0; valid = 0;
if (su_restore(idx, nbatch, &attr, 1, 0, &valid, 1)) { if (su_restore(idx, nbatch, NULL, &attr, 1, 0, &valid, 1)) {
try_to_fix_su(win, idx, None, nbatch, "unmapped"); try_to_fix_su(win, idx, None, nbatch, "unmapped");
if (valid) { if (valid) {
STORE(idx, win, attr); STORE(idx, win, attr);
@ -9007,6 +9131,16 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win
Ev_rects[nrects].y2 = cache_list[idx].height; Ev_rects[nrects].y2 = cache_list[idx].height;
nrects++; nrects++;
} }
x2 = cache_list[idx].x;
y2 = cache_list[idx].y;
w2 = cache_list[idx].width;
h2 = cache_list[idx].height;
r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(r, r0);
sraRgnOr(unmapped_rgn, r);
sraRgnDestroy(r);
cache_list[idx].map_state = IsUnmapped; cache_list[idx].map_state = IsUnmapped;
} else if (type == ReparentNotify) { } else if (type == ReparentNotify) {
@ -9043,6 +9177,8 @@ fprintf(stderr, "igno%02d: ** Ignoring 0x%x type: %s\n", ik, (unsigned int)
} }
} }
check_sched(try_batch, &did_sched);
if (n_CN || n_RN || n_DN || n_MN || n_UN || n_ST || did_sched) { if (n_CN || n_RN || n_DN || n_MN || n_UN || n_ST || did_sched) {
snap_old(); snap_old();
} }

@ -17,6 +17,8 @@ typedef struct winattr {
double time; double time;
double bs_time; double bs_time;
double su_time; double su_time;
double vis_obs_time;
double vis_unobs_time;
int bs_x, bs_y, bs_w, bs_h; int bs_x, bs_y, bs_w, bs_h;
int su_x, su_y, su_w, su_h; int su_x, su_y, su_w, su_h;
Window above; Window above;

@ -2,7 +2,7 @@
.TH X11VNC "1" "January 2007" "x11vnc " "User Commands" .TH X11VNC "1" "January 2007" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.4, lastmod: 2007-01-03 version: 0.8.4, lastmod: 2007-01-07
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...

@ -470,6 +470,10 @@ extern double x11vnc_start;
extern double last_get_wm_frame_time; extern double last_get_wm_frame_time;
extern Window last_get_wm_frame; extern Window last_get_wm_frame;
extern double last_bs_restore;
extern double last_su_restore;
extern double last_bs_save;
extern double last_su_save;
extern int hack_val; extern int hack_val;

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.4 lastmod: 2007-01-03"; char lastmod[] = "0.8.4 lastmod: 2007-01-07";
/* X display info */ /* X display info */
@ -134,6 +134,10 @@ double x11vnc_start = 0.0;
double last_get_wm_frame_time = 0.0; double last_get_wm_frame_time = 0.0;
Window last_get_wm_frame = None; Window last_get_wm_frame = None;
double last_bs_restore = 0.0;
double last_su_restore = 0.0;
double last_bs_save = 0.0;
double last_su_save = 0.0;
int hack_val = 0; int hack_val = 0;

@ -563,13 +563,22 @@ int xdamage_hint_skip(int y) {
if (ncache > 0) { if (ncache > 0) {
if (ncache_no_skip == 0) { if (ncache_no_skip == 0) {
if (dnow() > last_ncache_no_skip + 4.0) { double now = dnow();
if (now > last_ncache_no_skip + 8.0) {
ncache_no_skip = 1; ncache_no_skip = 1;
} else if (now < last_bs_restore + 0.5) {
ncache_no_skip = 1;
} else if (now < last_su_restore + 0.5) {
ncache_no_skip = 1;
} else if (now < last_copyrect + 0.5) {
ncache_no_skip = 1;
}
if (ncache_no_skip) {
last_ncache_no_skip = dnow(); last_ncache_no_skip = dnow();
return 0; return 0;
} }
} else { } else {
if (++ncache_no_skip >= 2*nreg) { if (ncache_no_skip++ >= 1*nreg + 4) {
ncache_no_skip = 0; ncache_no_skip = 0;
} else { } else {
return 0; return 0;

Loading…
Cancel
Save