From 7a13194a646c834819a7d048b51e17f8bc7a06a6 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Sun, 17 Feb 2019 13:33:25 +0000 Subject: [PATCH] ecore drm2 - work around kms/drm bug seemingly when no flip event comes so we request a flip so we can do vsync events. the flip event never comes. i am not sure why it never comes, but we ask and nothing arrives, and this basically halts all rendering in wayland compositor mode as we are syncing rendering to vsync (of course). put in a timeout of 0.05s (50ms) to try ask again if the event never comes and log the error. this is a pretty useful workaround becauswe having your entire display freeze is a ... bad thing. @fix --- src/lib/ecore_drm2/ecore_drm2_fb.c | 30 ++++++++++++++++++++++++++++++ src/lib/ecore_drm2/ecore_drm2_outputs.c | 2 ++ src/lib/ecore_drm2/ecore_drm2_private.h | 2 ++ 3 files changed, 34 insertions(+) diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c index 33c0e27..6888a3c 100644 --- a/src/lib/ecore_drm2/ecore_drm2_fb.c +++ b/src/lib/ecore_drm2/ecore_drm2_fb.c @@ -263,6 +263,11 @@ ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE); + if (output->flip_timeout) + { + ecore_timer_del(output->flip_timeout); + output->flip_timeout = NULL; + } if (output->current.fb && (output->current.fb != output->pending.fb)) _ecore_drm2_fb_buffer_release(output, &output->current); @@ -428,6 +433,21 @@ err: return EINA_FALSE; } +static int _fb_atomic_flip(Ecore_Drm2_Output *output); +static int _fb_flip(Ecore_Drm2_Output *output); + +static Eina_Bool +_cb_flip_timeout(void *data) +{ + Ecore_Drm2_Output *output = data; + + output->flip_timeout = NULL; + ERR("flip event callback timout 0.05sec - try again"); + if (_ecore_drm2_use_atomic) _fb_atomic_flip(output); + else _fb_flip(output); + return EINA_FALSE; +} + static int _fb_atomic_flip(Ecore_Drm2_Output *output) { @@ -453,6 +473,11 @@ _fb_atomic_flip(Ecore_Drm2_Output *output) ERR("Failed Atomic Commit: %m"); return -1; } + else + { + if (output->flip_timeout) ecore_timer_del(output->flip_timeout); + output->flip_timeout = ecore_timer_add(0.05, _cb_flip_timeout, output); + } return 0; } @@ -526,6 +551,11 @@ _fb_flip(Ecore_Drm2_Output *output) } usleep(100); } + else + { + if (output->flip_timeout) ecore_timer_del(output->flip_timeout); + output->flip_timeout = ecore_timer_add(0.05, _cb_flip_timeout, output); + } } while (repeat); diff --git a/src/lib/ecore_drm2/ecore_drm2_outputs.c b/src/lib/ecore_drm2/ecore_drm2_outputs.c index 557e33f..a820f7d 100644 --- a/src/lib/ecore_drm2/ecore_drm2_outputs.c +++ b/src/lib/ecore_drm2/ecore_drm2_outputs.c @@ -916,6 +916,8 @@ _output_destroy(Ecore_Drm2_Device *dev EINA_UNUSED, Ecore_Drm2_Output *output) eina_stringshare_del(output->serial); eina_stringshare_del(output->relative.to); + if (output->flip_timeout) ecore_timer_del(output->flip_timeout); + sym_drmModeFreeProperty(output->dpms); free(output->edid.blob); diff --git a/src/lib/ecore_drm2/ecore_drm2_private.h b/src/lib/ecore_drm2/ecore_drm2_private.h index 490f166..d1a749a 100644 --- a/src/lib/ecore_drm2/ecore_drm2_private.h +++ b/src/lib/ecore_drm2/ecore_drm2_private.h @@ -252,6 +252,8 @@ struct _Ecore_Drm2_Output /* unused when doing atomic */ drmModePropertyPtr dpms; + Ecore_Timer *flip_timeout; + Ecore_Drm2_Output_Mode *current_mode; Eina_List *modes; -- 2.7.4