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
This commit is contained in:
Carsten Haitzler 2019-02-17 13:33:25 +00:00
parent 2c259edd9f
commit 39f224b3a6
3 changed files with 34 additions and 0 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;