wayland: Better handle event times that cross zero

Detect times that cross forward/backward across the zero timepoint, and handle them appropriately, so that events with an old timestamp don't mangle the time base offset, or have their timestamps mangled.
This commit is contained in:
Frank Praznik
2025-10-13 13:04:27 -04:00
parent b067dfa345
commit 228a7d8e54

View File

@@ -215,16 +215,32 @@ static Uint64 Wayland_AdjustEventTimestampBase(Uint64 nsTimestamp)
*/
static Uint64 Wayland_EventTimestampMSToNS(Uint32 wl_timestamp_ms)
{
static const Uint32 ROLLOVER_INTERVAL_LOW = SDL_MAX_UINT32 / 16;
static const Uint32 ROLLOVER_INTERVAL_HIGH = ROLLOVER_INTERVAL_LOW * 15;
static Uint64 timestamp_offset = 0;
static Uint32 last = 0;
Uint64 timestamp = SDL_MS_TO_NS(wl_timestamp_ms) + timestamp_offset;
// Handle 32-bit timer rollover.
if (wl_timestamp_ms < last) {
timestamp_offset += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000));
if (wl_timestamp_ms >= last) {
if (timestamp_offset && last < ROLLOVER_INTERVAL_LOW && wl_timestamp_ms > ROLLOVER_INTERVAL_HIGH) {
// A time that crossed backwards across zero was received. Subtract the increased time base offset.
timestamp -= SDL_MS_TO_NS(SDL_UINT64_C(0x100000000));
} else {
last = wl_timestamp_ms;
}
} else {
/* Only increment the base time offset if the timer actually crossed forward across 0,
* and not if this is just a timestamp from a slightly older event.
*/
if (wl_timestamp_ms < ROLLOVER_INTERVAL_LOW && last > ROLLOVER_INTERVAL_HIGH) {
timestamp_offset += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000));
timestamp += SDL_MS_TO_NS(SDL_UINT64_C(0x100000000));
last = wl_timestamp_ms;
}
}
last = wl_timestamp_ms;
return SDL_MS_TO_NS(wl_timestamp_ms) + timestamp_offset;
return timestamp;
}
/* Even if high-res timestamps are available, the millisecond timestamps are still processed