wayland: Add SDL_VIDEO_DOUBLE_BUFFER support

Manual cherry-pick of 9e6b8d56e3

thanks @vanfanel
This commit is contained in:
Frank Praznik 2024-07-17 18:24:47 -04:00
parent 5db08b86ca
commit b99ea1ff75
No known key found for this signature in database
4 changed files with 26 additions and 5 deletions

View file

@ -2948,6 +2948,7 @@ extern "C" {
* This hint is currently supported on the following drivers:
*
* - Raspberry Pi (raspberrypi)
* - Wayland (wayland)
*
* This hint should be set before SDL is initialized.
*

View file

@ -120,6 +120,19 @@ int Wayland_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
return 0;
}
/* By default, we wait for the Wayland frame callback and then issue the pageflip (eglSwapBuffers),
* but if we want low latency (double buffer scheme), we issue the pageflip and then wait
* immediately for the 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 && data->surface_status == WAYLAND_SURFACE_STATUS_SHOWN) {
SDL_VideoData *videodata = _this->internal;
@ -161,12 +174,14 @@ int Wayland_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
SDL_AtomicSet(&data->swap_interval_ready, 0);
}
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);
}
return 0;
}

View file

@ -2484,6 +2484,10 @@ int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propert
data->surface_status = WAYLAND_SURFACE_STATUS_SHOWN;
}
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
data->double_buffer = SDL_TRUE;
}
SDL_PropertiesID props = SDL_GetWindowProperties(window);
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, data->waylandData->display);
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, data->surface);

View file

@ -168,6 +168,7 @@ struct SDL_WindowData
SDL_bool show_hide_sync_required;
SDL_bool scale_to_display;
SDL_bool modal_reparenting_required;
SDL_bool double_buffer;
SDL_HitTestResult hit_test_result;