Skip to content

Commit c45c4a5

Browse files
committed
render: SDL_HINT_RENDER_DRIVER now accepts a comma-separated list.
Fixes #11077.
1 parent 670a7d8 commit c45c4a5

File tree

3 files changed

+37
-20
lines changed

3 files changed

+37
-20
lines changed

include/SDL3/SDL_hints.h

+8
Original file line numberDiff line numberDiff line change
@@ -2900,6 +2900,10 @@ extern "C" {
29002900
* - "gpu"
29012901
* - "software"
29022902
*
2903+
* This hint accepts a comma-separated list of driver names, and each will
2904+
* be tried in the order listed when creating a renderer until one succeeds
2905+
* or all of them fail.
2906+
*
29032907
* The default varies by platform, but it's the first one in the list that is
29042908
* available on the current platform.
29052909
*
@@ -3289,6 +3293,10 @@ extern "C" {
32893293
* force a specific target, such as "x11" if, say, you are on Wayland but want
32903294
* to try talking to the X server instead.
32913295
*
3296+
* This hint accepts a comma-separated list of driver names, and each will
3297+
* be tried in the order listed during init, until one succeeds or all of them
3298+
* fail.
3299+
*
32923300
* This hint should be set before SDL is initialized.
32933301
*
32943302
* \since This hint is available since SDL 3.1.3.

include/SDL3/SDL_render.h

+3
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CreateWindowAndRenderer(const char *title,
219219
* don't need a specific renderer, specify NULL and SDL will attempt to choose
220220
* the best option for you, based on what is available on the user's system.
221221
*
222+
* If `name` is a comma-separated list, SDL will try each name, in the order
223+
* listed, until one succeeds or all of them fail.
224+
*
222225
* By default the rendering size matches the window size in pixels, but you
223226
* can call SDL_SetRenderLogicalPresentation() to change the content size and
224227
* scaling options.

src/render/SDL_render.c

+26-20
Original file line numberDiff line numberDiff line change
@@ -958,10 +958,8 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
958958
#ifndef SDL_RENDER_DISABLED
959959
SDL_Window *window = (SDL_Window *)SDL_GetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, NULL);
960960
SDL_Surface *surface = (SDL_Surface *)SDL_GetPointerProperty(props, SDL_PROP_RENDERER_CREATE_SURFACE_POINTER, NULL);
961-
const char *name = SDL_GetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, NULL);
962-
const int n = SDL_GetNumRenderDrivers();
961+
const char *driver_name = SDL_GetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, NULL);
963962
const char *hint;
964-
int i, attempted = 0;
965963
SDL_PropertiesID new_props;
966964

967965
#ifdef SDL_PLATFORM_ANDROID
@@ -1008,36 +1006,44 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
10081006
}
10091007
} else {
10101008
bool rc = false;
1011-
if (!name) {
1012-
name = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
1013-
}
1014-
1015-
if (name) {
1016-
for (i = 0; i < n; i++) {
1017-
const SDL_RenderDriver *driver = render_drivers[i];
1018-
if (SDL_strcasecmp(name, driver->name) == 0) {
1019-
// Create a new renderer instance
1020-
++attempted;
1021-
rc = driver->CreateRenderer(renderer, window, props);
1022-
break;
1009+
if (!driver_name) {
1010+
driver_name = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
1011+
}
1012+
1013+
if (driver_name && *driver_name != 0) {
1014+
const char *driver_attempt = driver_name;
1015+
while (driver_attempt && *driver_attempt != 0 && !rc) {
1016+
const char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
1017+
const size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt) : SDL_strlen(driver_attempt);
1018+
1019+
for (int i = 0; render_drivers[i]; i++) {
1020+
const SDL_RenderDriver *driver = render_drivers[i];
1021+
if ((driver_attempt_len == SDL_strlen(driver->name)) && (SDL_strncasecmp(driver->name, driver_attempt, driver_attempt_len) == 0)) {
1022+
rc = driver->CreateRenderer(renderer, window, props);
1023+
if (rc) {
1024+
break;
1025+
}
1026+
}
10231027
}
1028+
1029+
driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL;
10241030
}
10251031
} else {
1026-
for (i = 0; i < n; i++) {
1032+
for (int i = 0; render_drivers[i]; i++) {
10271033
const SDL_RenderDriver *driver = render_drivers[i];
1028-
// Create a new renderer instance
1029-
++attempted;
10301034
rc = driver->CreateRenderer(renderer, window, props);
10311035
if (rc) {
1032-
break; // Yay, we got one!
1036+
break;
10331037
}
10341038
SDL_DestroyRendererWithoutFreeing(renderer);
10351039
SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
10361040
}
10371041
}
10381042

10391043
if (!rc) {
1040-
if (!name || !attempted) {
1044+
if (driver_name) {
1045+
SDL_SetError("%s not available", driver_name);
1046+
} else {
10411047
SDL_SetError("Couldn't find matching render driver");
10421048
}
10431049
goto error;

0 commit comments

Comments
 (0)