Add VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER and move detection to video drivers (#14817)

This commit is contained in:
Cameron Cawley
2026-02-03 17:38:02 +00:00
committed by GitHub
parent 28ea4a8e31
commit eceb35c96c
7 changed files with 37 additions and 30 deletions

View File

@@ -191,7 +191,8 @@ typedef enum
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS = 0x04,
VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY = 0x08,
VIDEO_DEVICE_CAPS_SENDS_DISPLAY_CHANGES = 0x10,
VIDEO_DEVICE_CAPS_SENDS_HDR_CHANGES = 0x20
VIDEO_DEVICE_CAPS_SENDS_HDR_CHANGES = 0x20,
VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER = 0x40
} DeviceCaps;
// Fullscreen operations
@@ -404,7 +405,6 @@ struct SDL_VideoDevice
// Data common to all drivers
SDL_ThreadID thread;
bool checked_texture_framebuffer;
bool is_dummy;
bool suspend_screensaver;
void *wakeup_window;
int num_displays;

View File

@@ -69,12 +69,6 @@
#include <3ds.h>
#endif
#ifdef SDL_PLATFORM_LINUX
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#ifndef GL_RGBA_FLOAT_MODE_ARB
#define GL_RGBA_FLOAT_MODE_ARB 0x8820
#endif /* GL_RGBA_FLOAT_MODE_ARB */
@@ -222,6 +216,11 @@ static bool SDL_DriverSendsHDRChanges(SDL_VideoDevice *_this)
return !!(_this->device_caps & VIDEO_DEVICE_CAPS_SENDS_HDR_CHANGES);
}
static bool SDL_DriverHasSlowFramebuffer(SDL_VideoDevice *_this)
{
return !!(_this->device_caps & VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER);
}
// Hint to treat all window ops as synchronous
static bool syncHint;
@@ -3579,11 +3578,11 @@ bool SDL_SyncWindow(SDL_Window *window)
static bool ShouldAttemptTextureFramebuffer(void)
{
const char *hint;
bool attempt_texture_framebuffer = true;
bool attempt_texture_framebuffer;
// The dummy driver never has GPU support, of course.
if (_this->is_dummy) {
return false;
// If the driver doesn't support window framebuffers, always use the render API.
if (!_this->CreateWindowFramebuffer) {
return true;
}
// See if there's a hint override
@@ -3595,24 +3594,11 @@ static bool ShouldAttemptTextureFramebuffer(void)
attempt_texture_framebuffer = true;
}
} else {
// 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)) {
struct stat sb;
if ((stat("/proc/sys/fs/binfmt_misc/WSLInterop", &sb) == 0) || (stat("/run/WSL", &sb) == 0)) { // if either of these exist, we're on WSL.
attempt_texture_framebuffer = false;
}
}
#endif
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) // GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?)
if (_this->CreateWindowFramebuffer && (SDL_strcmp(_this->name, "windows") == 0)) {
if (SDL_DriverHasSlowFramebuffer(_this)) {
attempt_texture_framebuffer = true;
} else {
attempt_texture_framebuffer = false;
}
#endif
#ifdef SDL_PLATFORM_EMSCRIPTEN
attempt_texture_framebuffer = false;
#endif
}
return attempt_texture_framebuffer;
}

View File

@@ -100,7 +100,6 @@ static SDL_VideoDevice *DUMMY_InternalCreateDevice(const char *enable_hint)
if (!device) {
return NULL;
}
device->is_dummy = true;
// Set the function pointers
device->VideoInit = DUMMY_VideoInit;

View File

@@ -107,6 +107,9 @@ static SDL_VideoDevice * HAIKU_CreateDevice(void)
device->free = HAIKU_DeleteDevice;
// TODO: Is this needed?
device->device_caps = VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER;
return device;
}

View File

@@ -110,6 +110,9 @@ static SDL_VideoDevice *OFFSCREEN_CreateDevice(void)
device->DestroyWindow = OFFSCREEN_DestroyWindow;
device->SetWindowSize = OFFSCREEN_SetWindowSize;
// TODO: Is this needed?
device->device_caps = VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER;
return device;
}

View File

@@ -112,6 +112,7 @@ static SDL_VideoDevice *VITA_Create(void)
/*
// Disabled, causes issues on high-framerate updates. SDL still emulates this.
// TODO: Is VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER needed?
device->CreateWindowFramebuffer = VITA_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = VITA_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer;

View File

@@ -77,6 +77,16 @@ static bool X11_IsXWayland(Display *d)
return X11_XQueryExtension(d, "XWAYLAND", &opcode, &event, &error) == True;
}
static bool X11_IsWSL(void)
{
#ifdef SDL_PLATFORM_LINUX
if (SDL_GetPathInfo("/proc/sys/fs/binfmt_misc/WSLInterop", NULL) || SDL_GetPathInfo("/run/WSL", NULL)) { // if either of these exist, we're on WSL.
return true;
}
#endif
return false;
}
static SDL_VideoDevice *X11_CreateDevice(void)
{
SDL_VideoDevice *device;
@@ -255,7 +265,8 @@ static SDL_VideoDevice *X11_CreateDevice(void)
device->system_theme = SDL_SystemTheme_Get();
#endif
device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT;
device->device_caps = VIDEO_DEVICE_CAPS_HAS_POPUP_WINDOW_SUPPORT |
VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER;
data->is_xwayland = X11_IsXWayland(x11_display);
if (data->is_xwayland) {
@@ -264,6 +275,10 @@ static SDL_VideoDevice *X11_CreateDevice(void)
device->device_caps |= VIDEO_DEVICE_CAPS_MODE_SWITCHING_EMULATED |
VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
}
if (X11_IsWSL()) {
// On WSL, direct X11 is faster than using OpenGL for window framebuffers, so try to detect WSL and avoid texture framebuffer.
device->device_caps &= ~VIDEO_DEVICE_CAPS_SLOW_FRAMEBUFFER;
}
return device;
}