raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=60d78b5b9731337ed1b6f3f1b786d48df1501e97

commit 60d78b5b9731337ed1b6f3f1b786d48df1501e97
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Wed Oct 28 16:39:28 2015 +0900

    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 ea51bf5..ea35b5a 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;
           }
      }

-- 


Reply via email to