Skip to content

Commit

Permalink
video: Support multiple video driver entries having the same name string
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Kontrabant authored and slouken committed Aug 3, 2024
1 parent ab916a9 commit ca2c9f6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/video/SDL_sysvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
38 changes: 33 additions & 5 deletions src/video/SDL_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}
}

Expand Down
15 changes: 7 additions & 8 deletions src/video/wayland/SDL_waylandvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ca2c9f6

Please sign in to comment.