diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 9e03a86687ed5..6aeee58fd64ce 100644 --- a/src/video/SDL_sysvideo.h +++ b/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; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 353e110403819..578d06a5af1fd 100644 --- a/src/video/SDL_video.c +++ b/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; + } } } diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 7a5f2cb8747bc..3aa9b8705e18d 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -68,7 +68,6 @@ #include #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