wayland: don't hang in SDL_GL_SwapBuffers if the compositor is ghosting us.
If you hide a window on Mutter, for example, the compositor never requests new frames, which will cause Mesa to block forever in eglSwapBuffers to satisfy the swap interval. We now always set the swap interval to 0 and manage this ourselves, handing the frame to Wayland when it requests a new one, and timing out at 10fps just to keep apps moving if the compositor wants no frames at all. My understanding is that other protocols are coming that might improve upon this solution, but for now it solves the total hang. Fixes #4335.
This commit is contained in:
parent
227021b647
commit
c54c16d353
5 changed files with 97 additions and 7 deletions
|
@ -199,6 +199,22 @@ static const struct wl_shell_surface_listener shell_surface_listener_wl = {
|
|||
};
|
||||
|
||||
|
||||
static const struct wl_callback_listener surface_frame_listener;
|
||||
|
||||
static void
|
||||
handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time)
|
||||
{
|
||||
SDL_WindowData *wind = (SDL_WindowData *) data;
|
||||
SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */
|
||||
|
||||
/* reset this callback to fire again once a new frame was presented and compositor wants the next one. */
|
||||
wl_callback_destroy(cb);
|
||||
wl_callback_add_listener(wl_surface_frame(wind->surface), &surface_frame_listener, data);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener surface_frame_listener = {
|
||||
handle_surface_frame_done
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
|
@ -996,6 +1012,9 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
wl_compositor_create_surface(c->compositor);
|
||||
wl_surface_add_listener(data->surface, &surface_listener, data);
|
||||
|
||||
/* fire a callback when the compositor wants a new frame rendered. */
|
||||
wl_callback_add_listener(wl_surface_frame(data->surface), &surface_frame_listener, data);
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
if (c->surface_extension) {
|
||||
data->extended_surface = qt_surface_extension_get_extended_surface(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue