From 3129ef668abf2b3f9b624bdb4c5ac0365ae2583b Mon Sep 17 00:00:00 2001 From: runge Date: Thu, 8 Oct 2009 17:30:36 -0400 Subject: Huge number of changes, see x11vnc/ChangeLog --- x11vnc/xdamage.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'x11vnc/xdamage.c') diff --git a/x11vnc/xdamage.c b/x11vnc/xdamage.c index 9db86ae..946aff2 100644 --- a/x11vnc/xdamage.c +++ b/x11vnc/xdamage.c @@ -56,6 +56,8 @@ int xdamage_max_area = 20000; /* pixels */ double xdamage_memory = 1.0; /* in units of NSCAN */ int xdamage_tile_count = 0, xdamage_direct_count = 0; double xdamage_scheduled_mark = 0.0; +double xdamage_crazy_time = 0.0; +double xdamage_crazy_delay = 300.0; sraRegionPtr xdamage_scheduled_mark_region = NULL; sraRegionPtr *xdamage_regions = NULL; int xdamage_ticker = 0; @@ -400,6 +402,7 @@ int collect_xdamage(int scancnt, int call) { #define DUPSZ 32 int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ]; double tm, dt; + int mark_all = 0, retries = 0, too_many = 1000, tot_ev = 0; RAWFB_RET(0) @@ -443,6 +446,9 @@ int collect_xdamage(int scancnt, int call) { X_LOCK; if (0) XFlush_wr(dpy); if (0) XEventsQueued(dpy, QueuedAfterFlush); + + come_back_for_more: + while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) { /* * TODO max cut off time in this loop? @@ -450,6 +456,26 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush); * screen. */ ecount++; + tot_ev++; + + if (mark_all) { + continue; + } + if (ecount == too_many) { + int nqa = XEventsQueued(dpy, QueuedAlready); + if (nqa >= too_many) { + static double last_msg = 0.0; + tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y); + sraRgnOr(reg, tmpregion); + sraRgnDestroy(tmpregion); + if (dnow() > last_msg + xdamage_crazy_delay) { + rfbLog("collect_xdamage: too many xdamage events %d+%d\n", ecount, nqa); + last_msg = dnow(); + } + mark_all = 1; + } + } + if (ev.type != xdamage_base_event_type + XDamageNotify) { break; } @@ -537,12 +563,37 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush); rect_count++; ccount++; } + + if (mark_all) { + if (ecount + XEventsQueued(dpy, QueuedAlready) >= 3 * too_many && retries < 3) { + retries++; + XFlush_wr(dpy); + usleep(20 * 1000); + XFlush_wr(dpy); + ecount = 0; + goto come_back_for_more; + } + } + /* clear the whole damage region for next time. XXX check */ if (call == 1) { XDamageSubtract(dpy, xdamage, None, None); } X_UNLOCK; + if (tot_ev > 20 * too_many) { + rfbLog("collect_xdamage: xdamage has gone crazy (screensaver or game?) ev: %d ret: %d\n", tot_ev, retries); + rfbLog("collect_xdamage: disabling xdamage for %d seconds.\n", (int) xdamage_crazy_delay); + destroy_xdamage_if_needed(); + X_LOCK; + XSync(dpy, False); + while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) { + ; + } + X_UNLOCK; + xdamage_crazy_time = dnow(); + } + if (0 && xdamage_direct_count) { fb_push(); } @@ -726,7 +777,7 @@ void create_xdamage_if_needed(int force) { xdamage = XDamageCreate(dpy, window, XDamageReportRawRectangles); XDamageSubtract(dpy, xdamage, None, None); X_UNLOCK; - rfbLog("created xdamage object: 0x%lx\n", xdamage); + rfbLog("created xdamage object: 0x%lx\n", xdamage); } #endif } @@ -762,6 +813,9 @@ void check_xdamage_state(void) { * Create or destroy the Damage object as needed, we don't want * one if no clients are connected. */ + if (xdamage_crazy_time > 0.0 && dnow() < xdamage_crazy_time + xdamage_crazy_delay) { + return; + } if (client_count && use_xdamage) { create_xdamage_if_needed(0); if (xdamage_scheduled_mark > 0.0 && dnow() > -- cgit v1.1