From 703ca74d67d377d8901f94e0ff09320234f6d7c9 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 30 Apr 2019 11:49:12 +0100 Subject: [PATCH] ecore drm2 - fix timeout in case case called from thread so sw rendering make call ecore drm2 calls from a thread - i didnt know that. so this makes my fix for gl hangs add hangs in sw as a result. this fixes that. not perfect but better. do need refcoutnts on outputs to be perfect... also sometimes the commits fail so retry a few times... this still leaves us wth another hang that is a separate issue. @fix --- src/lib/ecore_drm2/ecore_drm2_fb.c | 52 ++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c index aab47956fb..e91cf67ec5 100644 --- a/src/lib/ecore_drm2/ecore_drm2_fb.c +++ b/src/lib/ecore_drm2/ecore_drm2_fb.c @@ -1,5 +1,7 @@ #include "ecore_drm2_private.h" +#define FLIP_TIMEOUT 0.05 + static Eina_Bool _fb2_create(Ecore_Drm2_Fb *fb) { @@ -255,6 +257,15 @@ _ecore_drm2_fb_buffer_release(Ecore_Drm2_Output *output EINA_UNUSED, Ecore_Drm2_ } } +static void +_cb_mainloop_async_timer_del(void *data) +{ + Ecore_Drm2_Output *output = data; + + ecore_timer_del(output->flip_timeout); + output->flip_timeout = NULL; +} + EAPI Eina_Bool ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) { @@ -265,9 +276,11 @@ ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) if (output->flip_timeout) { - ecore_timer_del(output->flip_timeout); - output->flip_timeout = NULL; + // XXX: output ref++ + ecore_main_loop_thread_safe_call_async + (_cb_mainloop_async_timer_del, output); } + if (!output->pending.fb) fprintf(stderr, "XXX--XXX eeeeek pending fb is NULL so current would become null ----------------------------------\n"); if (output->current.fb && (output->current.fb != output->pending.fb)) _ecore_drm2_fb_buffer_release(output, &output->current); @@ -470,12 +483,20 @@ _cb_flip_timeout(void *data) Ecore_Drm2_Output *output = data; output->flip_timeout = NULL; - ERR("flip event callback timout 0.05sec - try again"); + ERR("flip event callback timout %0.2fsec - try again", FLIP_TIMEOUT); if (_ecore_drm2_use_atomic) _fb_atomic_flip(output); else _fb_flip(output); return EINA_FALSE; } +static void +_cb_mainloop_async_timer_reset(void *data) +{ + Ecore_Drm2_Output *output = data; + if (output->flip_timeout) ecore_timer_del(output->flip_timeout); + output->flip_timeout = ecore_timer_add(FLIP_TIMEOUT, _cb_flip_timeout, output); +} + static int _fb_atomic_flip(Ecore_Drm2_Output *output) { @@ -493,9 +514,18 @@ _fb_atomic_flip(Ecore_Drm2_Output *output) /* Still no req is a bad situation */ EINA_SAFETY_ON_NULL_RETURN_VAL(output->prep.atomic_req, -1); - res = - sym_drmModeAtomicCommit(output->fd, output->prep.atomic_req, flags, - output); + // sometimes we get a EBUSY ... so try again a few times. + int i; + for (i = 0; i < 10; i++) + { + res = + sym_drmModeAtomicCommit(output->fd, output->prep.atomic_req, flags, + output); + if (res == 0) break; + else ERR("DRM atomic commit failed - retry #%i", i + 1); + usleep(100); + } + if (res < 0) { ERR("Failed Atomic Commit: %m"); @@ -503,8 +533,9 @@ _fb_atomic_flip(Ecore_Drm2_Output *output) } else { - if (output->flip_timeout) ecore_timer_del(output->flip_timeout); - output->flip_timeout = ecore_timer_add(0.05, _cb_flip_timeout, output); + // XXX: output ref++ + ecore_main_loop_thread_safe_call_async + (_cb_mainloop_async_timer_reset, output); } return 0; @@ -591,8 +622,9 @@ _fb_flip(Ecore_Drm2_Output *output) } else { - if (output->flip_timeout) ecore_timer_del(output->flip_timeout); - output->flip_timeout = ecore_timer_add(0.05, _cb_flip_timeout, output); + // XXX: output ref++ + ecore_main_loop_thread_safe_call_async + (_cb_mainloop_async_timer_reset, output); } } while (repeat);