summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2021-11-26 11:03:25 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2021-12-04 09:18:47 +0000
commit1d57aa2a4ce795150ab47706dad07edd12a2b632 (patch)
tree7d9aa38b879802f44b636f320c28abaab8dda509
parent711638c7d255401539078e1534e6bdb75e39803d (diff)
downloadefl-1d57aa2a4ce795150ab47706dad07edd12a2b632.tar.gz
ecore - loop time - do not allow setting into the future - not intended
setting a loop time timestamp in the future will lead to all sorts of bad things. the idea is it was meant to go back a little in time AFTER some sync/animation etc. event to pretend to be at the time when that event happend (it just took some time ot arrive at the process) and so animation and other timelines all agree to be at this time a little bit in the past. going forwards leads to bad things so disallow it and complain. this fixes weston in a window problems when it sends timestamps in the future from weston... @fix
-rw-r--r--src/lib/ecore/ecore_time.c10
-rw-r--r--src/lib/ecore_x/ecore_x_vsync.c50
2 files changed, 28 insertions, 32 deletions
diff --git a/src/lib/ecore/ecore_time.c b/src/lib/ecore/ecore_time.c
index 9f039e2b59..8f3d409e0b 100644
--- a/src/lib/ecore/ecore_time.c
+++ b/src/lib/ecore/ecore_time.c
@@ -79,6 +79,16 @@ ecore_loop_time_get(void)
EAPI void
ecore_loop_time_set(double t)
{
+ double tnow = ecore_time_get();
+ double tdelta = t - tnow;
+
+ if (tdelta > 0.0)
+ {
+ fprintf(stderr,
+ "Eccore: Trying to set loop time (%1.8f) %1.8fs too far in the future\n",
+ t, tdelta);
+ return;
+ }
efl_loop_time_set(ML_OBJ, t);
}
diff --git a/src/lib/ecore_x/ecore_x_vsync.c b/src/lib/ecore_x/ecore_x_vsync.c
index 1014542a6a..f505193722 100644
--- a/src/lib/ecore_x/ecore_x_vsync.c
+++ b/src/lib/ecore_x/ecore_x_vsync.c
@@ -178,7 +178,7 @@ _fallback_timeout(void *data EINA_UNUSED)
{
if (drm_event_is_busy)
{
- _drm_send_time(ecore_loop_time_get());
+ _drm_send_time(ecore_time_get());
return EINA_TRUE;
}
fallback_timer = NULL;
@@ -198,7 +198,7 @@ _fail_timeout(void *data EINA_UNUSED)
(1.0 / 60.0, _fallback_timeout, NULL);
}
if (drm_event_is_busy)
- _drm_send_time(ecore_loop_time_get());
+ _drm_send_time(ecore_time_get());
return EINA_FALSE;
}
@@ -383,46 +383,32 @@ _drm_vblank_handler(int fd EINA_UNUSED,
if (pframe != frame)
{
#define DELTA_COUNT 10
- double tnow = ecore_time_get();
double t = (double)sec + ((double)usec / 1000000);
- unsigned long long tusec, ptusec;
- static double tdelta[DELTA_COUNT];
- static double tdelta_avg = 0.0;
- static int tdelta_n = 0;
+ unsigned long long tusec, ptusec, tdelt = 0;
static unsigned int psec = 0, pusec = 0;
tusec = ((unsigned long long)sec) * 1000000 + usec;
ptusec = ((unsigned long long)psec) * 1000000 + pusec;
if (tusec <= ptusec)
- fprintf(stderr,
- "EEEEEEK! drm time went backwards! %u.%06u -> %u.%06u\n",
- psec, pusec, sec, usec);
- 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++;
- }
+ fprintf(stderr,
+ "EEEEEEK! drm time went backwards! %u.%06u -> %u.%06u\n",
+ psec, pusec, sec, usec);
}
else
{
- tdelta_avg = 0.0;
- tdelta_n = 0;
+ if (frame > pframe)
+ {
+ tdelt = (tusec - ptusec) / (frame - pframe);
+ // go back in time 1/8th of a frame to account for
+ // vlnbak gap - this should be enough for now.
+ // probably need to be a bit more accurate.
+ //
+ // why do this? because the timestamp is the time
+ // the top-left pixel is first displayed which is
+ // after the vlbank gap time
+ t -= (double)(tdelt / 8) / 1000000.0;
+ }
}
_drm_fail_count = 0;
_drm_send_time(t);