Respect SDL_HINT_RENDER_DRIVER when creating an accelerated window surface
Fixes https://github.com/libsdl-org/SDL/issues/10061
This commit is contained in:
parent
a522bfe3f1
commit
2a58e7b11c
1 changed files with 88 additions and 61 deletions
|
@ -297,23 +297,37 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, S
|
|||
|
||||
if (!data) {
|
||||
SDL_Renderer *renderer = NULL;
|
||||
const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
|
||||
const SDL_bool specific_accelerated_renderer = (hint && *hint != '0' && *hint != '1' &&
|
||||
const char *render_driver = NULL;
|
||||
const char *hint;
|
||||
|
||||
/* See if there's a render driver being requested */
|
||||
hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
|
||||
if (hint && *hint != '0' && *hint != '1' &&
|
||||
SDL_strcasecmp(hint, "true") != 0 &&
|
||||
SDL_strcasecmp(hint, "false") != 0 &&
|
||||
SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) != 0);
|
||||
SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) != 0) {
|
||||
render_driver = hint;
|
||||
}
|
||||
|
||||
if (!render_driver) {
|
||||
hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
|
||||
if (hint && *hint && SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) != 0) {
|
||||
render_driver = hint;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if there's a specific driver requested */
|
||||
if (specific_accelerated_renderer) {
|
||||
renderer = SDL_CreateRenderer(window, hint);
|
||||
if (render_driver) {
|
||||
renderer = SDL_CreateRenderer(window, render_driver);
|
||||
if (!renderer) {
|
||||
return SDL_SetError("Requested renderer for " SDL_HINT_FRAMEBUFFER_ACCELERATION " is not available");
|
||||
/* The error for this specific renderer has already been set */
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
const int total = SDL_GetNumRenderDrivers();
|
||||
for (i = 0; i < total; ++i) {
|
||||
const char *name = SDL_GetRenderDriver(i);
|
||||
if (name && (SDL_strcmp(name, SDL_SOFTWARE_RENDERER) != 0)) {
|
||||
if (name && SDL_strcmp(name, SDL_SOFTWARE_RENDERER) != 0) {
|
||||
renderer = SDL_CreateRenderer(window, name);
|
||||
if (renderer) {
|
||||
break; /* this will work. */
|
||||
|
@ -3231,36 +3245,26 @@ int SDL_SyncWindow(SDL_Window *window)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
||||
static SDL_bool ShouldAttemptTextureFramebuffer(void)
|
||||
{
|
||||
SDL_PixelFormatEnum format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
void *pixels = NULL;
|
||||
int pitch = 0;
|
||||
SDL_bool created_framebuffer = SDL_FALSE;
|
||||
int w, h;
|
||||
const char *hint;
|
||||
SDL_bool attempt_texture_framebuffer = SDL_TRUE;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
/* The dummy driver never has GPU support, of course. */
|
||||
if (_this->is_dummy) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* This will switch the video backend from using a software surface to
|
||||
using a GPU texture through the 2D render API, if we think this would
|
||||
be more efficient. This only checks once, on demand. */
|
||||
if (!_this->checked_texture_framebuffer) {
|
||||
SDL_bool attempt_texture_framebuffer;
|
||||
|
||||
if (_this->is_dummy) { /* dummy driver never has GPU support, of course. */
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
} else {
|
||||
/* See if the user or application wants to specifically disable the framebuffer */
|
||||
const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
|
||||
/* See if there's a hint override */
|
||||
hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
|
||||
if (hint && *hint) {
|
||||
if ((*hint == '0') || (SDL_strcasecmp(hint, "false") == 0) || (SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) == 0)) {
|
||||
if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0 || SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) == 0) {
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
} else {
|
||||
attempt_texture_framebuffer = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
attempt_texture_framebuffer = SDL_TRUE;
|
||||
|
||||
/* Check for platform specific defaults */
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
/* On WSL, direct X11 is faster than using OpenGL for window framebuffers, so try to detect WSL and avoid texture framebuffer. */
|
||||
if ((_this->CreateWindowFramebuffer) && (SDL_strcmp(_this->name, "x11") == 0)) {
|
||||
|
@ -3281,6 +3285,30 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
|||
}
|
||||
|
||||
if (attempt_texture_framebuffer) {
|
||||
/* Using a software renderer will try to display on a window surface, so avoid recursion here */
|
||||
hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
|
||||
if (hint && SDL_strcasecmp(hint, SDL_SOFTWARE_RENDERER) == 0) {
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
return attempt_texture_framebuffer;
|
||||
}
|
||||
|
||||
static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
||||
{
|
||||
SDL_PixelFormatEnum format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
void *pixels = NULL;
|
||||
int pitch = 0;
|
||||
SDL_bool created_framebuffer = SDL_FALSE;
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSizeInPixels(window, &w, &h);
|
||||
|
||||
/* This will switch the video backend from using a software surface to
|
||||
using a GPU texture through the 2D render API, if we think this would
|
||||
be more efficient. This only checks once, on demand. */
|
||||
if (!_this->checked_texture_framebuffer) {
|
||||
if (ShouldAttemptTextureFramebuffer()) {
|
||||
if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) < 0) {
|
||||
/* !!! FIXME: if this failed halfway (made renderer, failed to make texture, etc),
|
||||
!!! FIXME: we probably need to clean this up so it doesn't interfere with
|
||||
|
@ -3299,7 +3327,6 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window)
|
|||
created_framebuffer = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_this->checked_texture_framebuffer = SDL_TRUE; /* don't check this again. */
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue