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
This commit is contained in:
Carsten Haitzler 2015-10-28 16:39:28 +09:00
parent a089818335
commit 60d78b5b97
1 changed files with 35 additions and 1 deletions

View File

@ -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;
}
}