[client] x11: prevent present event loop underruns

Queue up and maintain a list of presentation timestamps to avoid spikes
caused by X11 event processing latency.
This commit is contained in:
Geoffrey McRae 2021-08-09 15:24:12 +10:00
parent 179eaef29d
commit bc7e59c9d7

View File

@ -84,25 +84,74 @@ static void x11XPresentEvent(XGenericEventCookie *cookie);
static void x11DoPresent(void) static void x11DoPresent(void)
{ {
XPresentPixmap( static bool startup = true;
x11.display, if (startup)
x11.window, {
x11.presentPixmap, XPresentPixmap(
x11.presentSerial++, x11.display,
x11.presentRegion, // valid x11.window,
x11.presentRegion, // update x11.presentPixmap,
0, // x_off, x11.presentSerial++,
0, // y_off, x11.presentRegion, // valid
None, // target_crtc x11.presentRegion, // update
None, // wait_fence 0, // x_off,
None, // idle_fence 0, // y_off,
PresentOptionNone, // options None, // target_crtc
0, // target_msc, None, // wait_fence
0, // divisor, None, // idle_fence
0, // remainder, PresentOptionNone, // options
NULL, // notifies 0, // target_msc,
0 // nnotifies 0, // divisor,
); 0, // remainder,
NULL, // notifies
0 // nnotifies
);
startup = false;
return;
}
static bool first = true;
static uint64_t lastMsc = 0;
uint64_t msc = atomic_load(&x11.presentMsc);
uint64_t refill;
if (!first)
refill = 50 - (lastMsc - msc);
else
{
refill = 50;
first = false;
lastMsc = msc;
}
if (refill < 25)
return;
if (refill == 0)
lastMsc = msc;
for(int i = 0; i < refill; ++i)
{
XPresentPixmap(
x11.display,
x11.window,
x11.presentPixmap,
x11.presentSerial++,
x11.presentRegion, // valid
x11.presentRegion, // update
0, // x_off,
0, // y_off,
None, // target_crtc
None, // wait_fence
None, // idle_fence
PresentOptionNone, // options
++lastMsc, // target_msc,
0, // divisor,
0, // remainder,
NULL, // notifies
0 // nnotifies
);
}
} }
static void x11Setup(void) static void x11Setup(void)