diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index ec8d707b..32e83161 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -1030,12 +1030,72 @@ static void x11XInputEvent(XGenericEventCookie *cookie) static void x11XPresentEvent(XGenericEventCookie *cookie) { +#define CALIBRATION_COUNT 200 + uint64_t deltats = 0; + uint64_t deltamsc = 0; + switch(cookie->evtype) { case PresentCompleteNotify: { - lgSignalEvent(x11.frameEvent); x11DoPresent(); + + XPresentCompleteNotifyEvent * e = cookie->data; + + /* calibrate a delay to push our presentation time forward as far as + * possible without skipping frames */ + static int calibrate = 0; + static uint64_t lastts = 0; + static uint64_t lastmsc = 0; + static uint64_t delay = 0; + if (lastts) + { + deltats = e->ust - lastts; + deltamsc = e->msc - lastmsc; + + if (calibrate == 0) + { + if (!delay) + delay = deltats / 2; + else + { + /* increase the delay until we see a skip */ + if (deltamsc < 2) + delay += 100; + else + { + delay -= 100; + ++calibrate; + } + } + } + else + { + if (calibrate < CALIBRATION_COUNT) + { + /* every skip we back off the delay */ + if (deltamsc > 1) + { + delay -= 100; + calibrate = 1; + } + + /* if we have finished, print out the delay */ + if (++calibrate == CALIBRATION_COUNT) + DEBUG_INFO("Calibration done, delay = %lu us", delay); + } + } + } + + lastts = e->ust; + lastmsc = e->msc; + + /* minor adjustments if we are still seeing odd skips */ + if (deltamsc > 1) + delay -= 10; + + usleep(delay); + lgSignalEvent(x11.frameEvent); break; } }