Просмотр исходного кода

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

Cameron Cawley 1 месяц назад
Родитель
Сommit
eceb35c96c

+ 2 - 2
src/video/SDL_sysvideo.h

@@ -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;

+ 12 - 26
src/video/SDL_video.c

@@ -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;
 }

+ 0 - 1
src/video/dummy/SDL_nullvideo.c

@@ -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;

+ 3 - 0
src/video/haiku/SDL_bvideo.cc

@@ -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;
 }
 

+ 3 - 0
src/video/offscreen/SDL_offscreenvideo.c

@@ -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;
 }
 

+ 1 - 0
src/video/vita/SDL_vitavideo.c

@@ -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;

+ 16 - 1
src/video/x11/SDL_x11video.c

@@ -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;
 }