Parcourir la source

video: Support multiple video driver entries having the same name string

Allow multiple bootstrap entries for a single video driver with the same name, which internally allows preferential and fallback init conditions while hiding the implementation details from applications (e.g. applications will just see "wayland", regardless of whether it's using the preferred or fallback driver list entry).

If a driver is requested, all instances of it in the list will be tried before reporting failure, and client applications programmatically enumerating the video drivers will be presented with a deduplicated list of entries.
Frank Praznik il y a 1 an
Parent
commit
ca2c9f680b
3 fichiers modifiés avec 41 ajouts et 14 suppressions
  1. 1 1
      src/video/SDL_sysvideo.h
  2. 33 5
      src/video/SDL_video.c
  3. 7 8
      src/video/wayland/SDL_waylandvideo.c

+ 1 - 1
src/video/SDL_sysvideo.h

@@ -504,7 +504,7 @@ extern VideoBootStrap KMSDRM_bootstrap;
 extern VideoBootStrap DUMMY_bootstrap;
 extern VideoBootStrap DUMMY_evdev_bootstrap;
 extern VideoBootStrap Wayland_preferred_bootstrap;
-extern VideoBootStrap Wayland_fallback_bootstrap;
+extern VideoBootStrap Wayland_bootstrap;
 extern VideoBootStrap VIVANTE_bootstrap;
 extern VideoBootStrap Emscripten_bootstrap;
 extern VideoBootStrap OFFSCREEN_bootstrap;

+ 33 - 5
src/video/SDL_video.c

@@ -70,14 +70,14 @@ static VideoBootStrap *bootstrap[] = {
 #ifdef SDL_VIDEO_DRIVER_COCOA
     &COCOA_bootstrap,
 #endif
+#ifdef SDL_VIDEO_DRIVER_X11
 #ifdef SDL_VIDEO_DRIVER_WAYLAND
     &Wayland_preferred_bootstrap,
 #endif
-#ifdef SDL_VIDEO_DRIVER_X11
     &X11_bootstrap,
 #endif
 #ifdef SDL_VIDEO_DRIVER_WAYLAND
-    &Wayland_fallback_bootstrap,
+    &Wayland_bootstrap,
 #endif
 #ifdef SDL_VIDEO_DRIVER_VIVANTE
     &VIVANTE_bootstrap,
@@ -514,15 +514,41 @@ static int SDL_UninitializedVideo(void)
     return SDL_SetError("Video subsystem has not been initialized");
 }
 
+/* Deduplicated list of video bootstrap drivers. */
+static const VideoBootStrap *deduped_bootstrap[SDL_arraysize(bootstrap) - 1];
+
 int SDL_GetNumVideoDrivers(void)
 {
-    return SDL_arraysize(bootstrap) - 1;
+    static int num_drivers = -1;
+
+    if (num_drivers >= 0) {
+        return num_drivers;
+    }
+
+    num_drivers = 0;
+
+    /* Build a list of unique video drivers. */
+    for (int i = 0; bootstrap[i] != NULL; ++i) {
+        SDL_bool duplicate = SDL_FALSE;
+        for (int j = 0; j < i; ++j) {
+            if (SDL_strcmp(bootstrap[i]->name, bootstrap[j]->name) == 0) {
+                duplicate = SDL_TRUE;
+                break;
+            }
+        }
+
+        if (!duplicate) {
+            deduped_bootstrap[num_drivers++] = bootstrap[i];
+        }
+    }
+
+    return num_drivers;
 }
 
 const char *SDL_GetVideoDriver(int index)
 {
     if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
-        return bootstrap[index]->name;
+        return deduped_bootstrap[index]->name;
     }
     return NULL;
 }
@@ -580,7 +606,9 @@ int SDL_VideoInit(const char *driver_name)
                 if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) &&
                     (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) {
                     video = bootstrap[i]->create();
-                    break;
+                    if (video) {
+                        break;
+                    }
                 }
             }
 

+ 7 - 8
src/video/wayland/SDL_waylandvideo.c

@@ -68,7 +68,6 @@
 #include <libdecor.h>
 #endif
 
-#define WAYLANDVID_PREFERRED_DRIVER_NAME "wayland_preferred"
 #define WAYLANDVID_DRIVER_NAME "wayland"
 
 /* Clamp certain core protocol versions on older versions of libwayland. */
@@ -420,7 +419,7 @@ static SDL_bool Wayland_IsPreferred(struct wl_display *display)
     return preferred_data.has_fifo_v1 && preferred_data.has_commit_timing_v1;
 }
 
-static SDL_VideoDevice *Wayland_CreateDevice(SDL_bool fallback)
+static SDL_VideoDevice *Wayland_CreateDevice(SDL_bool require_preferred_protocols)
 {
     SDL_VideoDevice *device;
     SDL_VideoData *data;
@@ -451,11 +450,11 @@ static SDL_VideoDevice *Wayland_CreateDevice(SDL_bool fallback)
 
     /*
      * If we are checking for preferred Wayland, then let's query for
-     * fifo-v1 and commit-timing-v1's existance so we don't regress
+     * fifo-v1 and commit-timing-v1's existence, so we don't regress
      * GPU-bound performance and frame-pacing by default due to
      * swapchain starvation.
      */
-    if (!fallback && !Wayland_IsPreferred(display)) {
+    if (require_preferred_protocols && !Wayland_IsPreferred(display)) {
         WAYLAND_wl_display_disconnect(display);
         SDL_WAYLAND_UnloadSymbols();
         return NULL;
@@ -596,21 +595,21 @@ static SDL_VideoDevice *Wayland_CreateDevice(SDL_bool fallback)
 
 static SDL_VideoDevice *Wayland_Preferred_CreateDevice(void)
 {
-    return Wayland_CreateDevice(SDL_FALSE);
+    return Wayland_CreateDevice(SDL_TRUE);
 }
 
 static SDL_VideoDevice *Wayland_Fallback_CreateDevice(void)
 {
-    return Wayland_CreateDevice(SDL_TRUE);
+    return Wayland_CreateDevice(SDL_FALSE);
 }
 
 VideoBootStrap Wayland_preferred_bootstrap = {
-    WAYLANDVID_PREFERRED_DRIVER_NAME, "SDL Wayland video driver",
+    WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
     Wayland_Preferred_CreateDevice,
     Wayland_ShowMessageBox
 };
 
-VideoBootStrap Wayland_fallback_bootstrap = {
+VideoBootStrap Wayland_bootstrap = {
     WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver",
     Wayland_Fallback_CreateDevice,
     Wayland_ShowMessageBox