Skip to content

Commit

Permalink
Add SDL_VIDEO_DOUBLE_BUFFER support to the Wayland backend.
Browse files Browse the repository at this point in the history
(cherry picked from commit 9e6b8d5)
  • Loading branch information
vanfanel authored and slouken committed Sep 8, 2024
1 parent 00a7191 commit 1df907b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,7 @@ extern "C" {
* Since it's driver-specific, it's only supported where possible and
* implemented. Currently supported the following drivers:
*
* - Wayland (wayland)
* - KMSDRM (kmsdrm)
* - Raspberry Pi (raspberrypi)
*/
Expand Down
26 changes: 21 additions & 5 deletions src/video/wayland/SDL_waylandopengles.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
return 0;
}

/* By default, we wait for Wayland frame callback and then issue pageflip (eglSwapBuffers),
* but if we want low latency (double buffer scheme), we issue the pageflip
* and then wait immediately for Wayland frame callback.
*/

if (data->double_buffer) {
/* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */
if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) {
return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
}

WAYLAND_wl_display_flush(data->waylandData->display);
}

/* Control swap interval ourselves. See comments on Wayland_GLES_SetSwapInterval */
if (swap_interval != 0) {
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
Expand Down Expand Up @@ -162,12 +176,14 @@ int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
SDL_AtomicSet(&data->swap_interval_ready, 0);
}

/* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */
if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) {
return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
}
if (!data->double_buffer) {
/* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */
if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) {
return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
}

WAYLAND_wl_display_flush(data->waylandData->display);
WAYLAND_wl_display_flush(data->waylandData->display);
}

return 0;
}
Expand Down
5 changes: 5 additions & 0 deletions src/video/wayland/SDL_waylandwindow.c
Original file line number Diff line number Diff line change
Expand Up @@ -2023,6 +2023,11 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
}
}

data->double_buffer = SDL_FALSE;
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
data->double_buffer = SDL_TRUE;
}

data->outputs = NULL;
data->num_outputs = 0;

Expand Down
1 change: 1 addition & 0 deletions src/video/wayland/SDL_waylandwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ typedef struct
SDL_bool is_fullscreen;
SDL_bool in_fullscreen_transition;
Uint32 fullscreen_flags;
SDL_bool double_buffer;
} SDL_WindowData;

extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
Expand Down

0 comments on commit 1df907b

Please sign in to comment.