From 60d78b5b9731337ed1b6f3f1b786d48df1501e97 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 28 Oct 2015 16:39:28 +0900 Subject: [PATCH] efl - make drm vsync handle broken drm irq timestamps i found that intel drm device gives BROKEN timestamps vs system clock - it is off by about 0.3 to 0.4ms - this means the vsync event is in the future vs when we actually wake up and do processing - this leads to bizare timelines and likely odd event and animation handling. fix this by detecting it and figuring out an average delay and offsetting events by that in future, but until then, use "now" when the drm thread wakes up as the timestamp. @fix --- src/lib/ecore_x/xlib/ecore_x_vsync.c | 36 +++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/lib/ecore_x/xlib/ecore_x_vsync.c b/src/lib/ecore_x/xlib/ecore_x_vsync.c index ea51bf59f9..ea35b5a4ff 100644 --- a/src/lib/ecore_x/xlib/ecore_x_vsync.c +++ b/src/lib/ecore_x/xlib/ecore_x_vsync.c @@ -227,7 +227,41 @@ _drm_vblank_handler(int fd EINA_UNUSED, D(" @%1.5f vblank %i\n", ecore_time_get(), frame); if (pframe != frame) { - _drm_send_time((double)sec + ((double)usec / 1000000)); +#define DELTA_COUNT 10 + double t = (double)sec + ((double)usec / 1000000); + double tnow = ecore_time_get(); + static double tdelta[DELTA_COUNT]; + static double tdelta_avg = 0.0; + static int tdelta_n = 0; + + if (t > tnow) + { + if (tdelta_n > DELTA_COUNT) + { + t = t + tdelta_avg; + } + else if (tdelta_n < DELTA_COUNT) + { + tdelta[tdelta_n] = tnow - t; + tdelta_n++; + t = tnow; + } + else if (tdelta_n == DELTA_COUNT) + { + int i; + + for (i = 0; i < DELTA_COUNT; i++) + tdelta_avg += tdelta[i]; + tdelta_avg /= (double)(DELTA_COUNT); + tdelta_n++; + } + } + else + { + tdelta_avg = 0.0; + tdelta_n = 0; + } + _drm_send_time(t); pframe = frame; } }