summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2021-02-01 13:05:11 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2021-02-01 18:06:43 +0000
commit6f803ad233e397709a97a585aede4a8c3c8f0094 (patch)
tree92c68bc0b3e7c685403e5f79882fdbdfaca9d245
parent77c9adf1fd5030f5e07e678df9680ded5d93f501 (diff)
downloadefl-6f803ad233e397709a97a585aede4a8c3c8f0094.tar.gz
ecore x - allow vsync animator to delay by some fraction of a frame
@feat
-rw-r--r--src/lib/ecore_x/Ecore_X.h1
-rw-r--r--src/lib/ecore_x/ecore_x_vsync.c41
2 files changed, 42 insertions, 0 deletions
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index ae82a549ce..8eb235b5fb 100644
--- a/src/lib/ecore_x/Ecore_X.h
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -2610,6 +2610,7 @@ EAPI void *ecore_x_input_device_property_get(int slot, const char *prop
EAPI void ecore_x_input_device_property_set(int slot, const char *prop, void *data, int num, Ecore_X_Atom format, int unit_size); /**< @since 1.24 */
EAPI Eina_Bool ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win);
+EAPI void ecore_x_vsync_animator_tick_delay_set(double delay); /** < @since 1.26 */
typedef enum _Ecore_X_Gesture_Event_Mask
{
diff --git a/src/lib/ecore_x/ecore_x_vsync.c b/src/lib/ecore_x/ecore_x_vsync.c
index ff72d9f270..07abbabcca 100644
--- a/src/lib/ecore_x/ecore_x_vsync.c
+++ b/src/lib/ecore_x/ecore_x_vsync.c
@@ -29,6 +29,8 @@ int _ecore_x_image_shm_check(void);
static int _vsync_log_dom = -1;
+static double _ecore_x_vsync_animator_tick_delay = 0.0;
+
#undef ERR
#define ERR(...) EINA_LOG_DOM_ERR(_vsync_log_dom, __VA_ARGS__)
@@ -293,6 +295,39 @@ _drm_send_time(double t)
{
*tim = t;
DBG(" ... send %1.8f", t);
+ // if we are the wm/compositor we need to offset out vsync by 1/2
+ // a frame ... we should never offset by more than
+ // frame_time - render_time though ... but we don't know what
+ // this is and this varies... so for now this will do.a
+ if (_ecore_x_vsync_animator_tick_delay > 0.0)
+ {
+ static double t_last = 0.0;
+ static double t_delta_hist[10] = { 0.0 };
+ double t_delta = t - t_last;
+ double t_delta_min = 0.0;
+ double t_sleep = 0.0;
+
+ // if time delta is sane like 1/20th of a sec or less..
+ if (t_delta < (1.0 / 20.0))
+ {
+ int i;
+
+ for (i = 0; i < 9; i++)
+ t_delta_hist[i] = t_delta_hist[i + 1];
+ t_delta_hist[9] = t_delta;
+ t_delta_min = t_delta_hist[0];
+ for (i = 1; i < 10; i++)
+ {
+ if (t_delta_hist[i] < t_delta_min)
+ t_delta_min = t_delta_hist[i];
+ }
+ t_sleep = t_delta_min * _ecore_x_vsync_animator_tick_delay;
+ // if w'ere sleeping too long - don't sleep at all.
+ if (t_sleep > (1.0 / 20.0)) t_sleep = 0.0;
+ }
+ usleep(t_sleep * 1000000.0);
+ t_last = t;
+ }
D(" @%1.5f ... send %1.8f\n", ecore_time_get(), t);
eina_spinlock_take(&tick_queue_lock);
tick_queue_count++;
@@ -929,3 +964,9 @@ ecore_x_vsync_animator_tick_source_set(Ecore_X_Window win)
}
return EINA_TRUE;
}
+
+EAPI void
+ecore_x_vsync_animator_tick_delay_set(double delay)
+{
+ _ecore_x_vsync_animator_tick_delay = delay;
+}