[client] fix hang in eglSwapBuffers when exiting while not visible

eglSwapBuffers is allowed to block when called with a nonzero interval
parameter. On Wayland, Mesa will block until a frame callback arrives.
If an application is not visible, a compositor is free to not schedule
frame callbacks (in order to save CPU time rendering something that is
entirely invisible).

Currently, starting Looking Glass from a terminal, hiding it
entirely, and sending ^C will cause Looking Glass to hang joining the
render thread until the window is made visible again.

Calling eglDestroySurface is insufficient to unblock eglSwapBuffers, as
it attempts to grab the same underlying mutex.

Instead, this commit makes it so that we pass a 0 interval to
eglSwapBuffers when running on Wayland, such that we don't block waiting
for a frame callback. This is not entirely ideal as it *does* mean
Looking Glass submits buffers while hidden, but it seems better than
hanging on exit.

It also forces opengl:vsync and egl:vsync flags to off when running on
Wayland, as they are meaningless there.
This commit is contained in:
Tudor Brindus 2021-01-03 21:09:55 -05:00 committed by Geoffrey McRae
parent bc2f26b86d
commit 4bceaf5505
2 changed files with 25 additions and 2 deletions

View file

@ -97,6 +97,16 @@ struct Inst
LG_FontObj fontObj; LG_FontObj fontObj;
}; };
static bool egl_vsync_option_validator(struct Option * opt, const char ** error)
{
if (opt->value.x_bool && getenv("WAYLAND_DISPLAY"))
{
DEBUG_WARN("Cannot disable vsync on Wayland, forcing egl:vsync=off");
opt->value.x_bool = false;
}
return true;
}
static struct Option egl_options[] = static struct Option egl_options[] =
{ {
@ -105,7 +115,8 @@ static struct Option egl_options[] =
.name = "vsync", .name = "vsync",
.description = "Enable vsync", .description = "Enable vsync",
.type = OPTION_TYPE_BOOL, .type = OPTION_TYPE_BOOL,
.value.x_bool = false .value.x_bool = false,
.validator = &vsync_option_validator
}, },
{ {
.module = "egl", .module = "egl",

View file

@ -48,6 +48,17 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#define FADE_TIME 1000000 #define FADE_TIME 1000000
static bool opengl_vsync_option_validator(struct Option * opt, const char ** error)
{
if (opt->value.x_bool && getenv("WAYLAND_DISPLAY"))
{
DEBUG_WARN("Cannot disable vsync on Wayland, forcing opengl:vsync=off");
opt->value.x_bool = false;
}
return true;
}
static struct Option opengl_options[] = static struct Option opengl_options[] =
{ {
{ {
@ -62,7 +73,8 @@ static struct Option opengl_options[] =
.name = "vsync", .name = "vsync",
.description = "Enable vsync", .description = "Enable vsync",
.type = OPTION_TYPE_BOOL, .type = OPTION_TYPE_BOOL,
.value.x_bool = false .value.x_bool = false,
.validator = &vsync_option_validator
}, },
{ {
.module = "opengl", .module = "opengl",