Procházet zdrojové kódy

Add SDL_VIDEO_DOUBLE_BUFFER support to the Wayland backend.

vanfanel před 9 měsíci
rodič
revize
9e6b8d56e3

+ 1 - 0
include/SDL_hints.h

@@ -2213,6 +2213,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)
  */

+ 21 - 5
src/video/wayland/SDL_waylandopengles.c

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

+ 5 - 0
src/video/wayland/SDL_waylandwindow.c

@@ -1963,6 +1963,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;
 

+ 1 - 0
src/video/wayland/SDL_waylandwindow.h

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