diff --git a/CMakeLists.txt b/CMakeLists.txt index a36d82acdd50c..648671f70ab9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,6 +320,7 @@ dep_option(SDL_ARMNEON "Use NEON assembly routines" ON "SDL_ASSEMBLY dep_option(SDL_LSX "Use LSX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) dep_option(SDL_LASX "Use LASX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) +dep_option(SDL_DLOPEN_NOTES "Record dlopen dependencies in .note.dlopen section" TRUE UNIX_SYS OFF) set_option(SDL_LIBC "Use the system C library" ${SDL_LIBC_DEFAULT}) set_option(SDL_SYSTEM_ICONV "Use iconv() from system-installed libraries" ${SDL_SYSTEM_ICONV_DEFAULT}) set_option(SDL_LIBICONV "Prefer iconv() from libiconv, if available, over libc version" OFF) @@ -1559,6 +1560,25 @@ elseif(EMSCRIPTEN) CheckLibUnwind() elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) + + if(SDL_DLOPEN_NOTES) + set(CHECK_ELF_DLNOTES_SRC [==[ + #ifndef __ELF__ + ELF DL notes is only supported on ELF platforms + #endif + __attribute__ ((used,aligned(4),section(".note.dlopen"))) static const struct { + struct { int a; int b; int c; } hdr; char name[4]; __attribute__((aligned(4))) char json[24]; + } dlnote = { { 4, 0x407c0c0aU, 16 }, "FDO", "[\\"a\\":{\\"a\\":\\"1\\",\\"b\\":\\"2\\"}]" }; + int main(int argc, char *argv[]) { + return argc + dlnote.hdr.a; + } + ]==]) + check_c_source_compiles("${CHECK_ELF_DLNOTES_SRC}" COMPILER_SUPPORTS_ELFNOTES) + if(COMPILER_SUPPORTS_ELFNOTES) + set(HAVE_DLOPEN_NOTES TRUE) + endif() + endif() + if(SDL_AUDIO) if(NETBSD) set(SDL_AUDIO_DRIVER_NETBSD 1) diff --git a/docs/README-linux.md b/docs/README-linux.md index 8399881cd8aaa..daf8b03c53ace 100644 --- a/docs/README-linux.md +++ b/docs/README-linux.md @@ -26,7 +26,7 @@ Ubuntu 22.04+ can also add `libpipewire-0.3-dev libwayland-dev libdecor-0-dev li Fedora 35, all available features enabled: sudo yum install gcc git-core make cmake \ - alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ + alsa-lib-devel pulseaudio-libs-devel pipewire-devel \ libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ libXi-devel libXScrnSaver-devel dbus-devel ibus-devel \ systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index c8c02894a13fb..a2fd8e1d78ad3 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -231,6 +231,8 @@ #cmakedefine HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR 1 #cmakedefine HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP 1 +#cmakedefine HAVE_DLOPEN_NOTES 1 + /* SDL internal assertion support */ #cmakedefine SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED 1 #ifdef SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED diff --git a/src/SDL_internal.h b/src/SDL_internal.h index a345252f3a115..d0d1df58ba263 100644 --- a/src/SDL_internal.h +++ b/src/SDL_internal.h @@ -63,6 +63,7 @@ #include "SDL_build_config.h" #include "dynapi/SDL_dynapi.h" +#include "dynapi/SDL_dynapi_dlopennote.h" #if SDL_DYNAMIC_API #include "dynapi/SDL_dynapi_overrides.h" diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c index 5436be070aff5..8f3f00d3fa27b 100644 --- a/src/audio/aaudio/SDL_aaudio.c +++ b/src/audio/aaudio/SDL_aaudio.c @@ -53,6 +53,13 @@ struct SDL_PrivateAudioData #define LIB_AAUDIO_SO "libaaudio.so" +SDL_ELF_NOTE_DLOPEN( + "audio-aaudio", + "Support for audio through AAudio", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + LIB_AAUDIO_SO +); + typedef struct AAUDIO_Data { SDL_SharedObject *handle; @@ -308,8 +315,8 @@ static bool BuildAAudioStream(SDL_AudioDevice *device) ctx.AAudioStreamBuilder_setFormat(builder, format); ctx.AAudioStreamBuilder_setSampleRate(builder, device->spec.freq); ctx.AAudioStreamBuilder_setChannelCount(builder, device->spec.channels); - - // If no specific buffer size has been requested, the device will pick the optimal + + // If no specific buffer size has been requested, the device will pick the optimal if(SDL_GetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES)) { ctx.AAudioStreamBuilder_setBufferCapacityInFrames(builder, 2 * device->sample_frames); // AAudio requires that the buffer capacity is at least ctx.AAudioStreamBuilder_setFramesPerDataCallback(builder, device->sample_frames); // twice the size of the data callback buffer size diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index badbc43ec867e..1ee89933ce152 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -207,6 +207,13 @@ static bool load_alsa_syms(void) #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "audio-libalsa", + "Support for audio through libalsa", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_AUDIO_DRIVER_ALSA_DYNAMIC +); + static void UnloadALSALibrary(void) { if (alsa_handle) { diff --git a/src/audio/jack/SDL_jackaudio.c b/src/audio/jack/SDL_jackaudio.c index 3ae5137a580e8..49dff5fc91dbf 100644 --- a/src/audio/jack/SDL_jackaudio.c +++ b/src/audio/jack/SDL_jackaudio.c @@ -50,6 +50,13 @@ static bool load_jack_syms(void); #ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "audio-libjack", + "Support for audio through libjack", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_AUDIO_DRIVER_JACK_DYNAMIC +); + static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC; static SDL_SharedObject *jack_handle = NULL; diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index b934877b2cc12..fede5fbf35bdc 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -93,6 +93,13 @@ static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, #ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "audio-libpipewire", + "Support for audio through libpipewire", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC +); + static const char *pipewire_library = SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC; static SDL_SharedObject *pipewire_handle = NULL; diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index 69e8c1a84c8b3..4c6f4278811fa 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -133,6 +133,13 @@ static bool load_pulseaudio_syms(void); #ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "audio-libpulseaudio", + "Support for audio through libpulseaudio", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC +); + static const char *pulseaudio_library = SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC; static SDL_SharedObject *pulseaudio_handle = NULL; diff --git a/src/audio/sndio/SDL_sndioaudio.c b/src/audio/sndio/SDL_sndioaudio.c index a0d20209b5cf9..1cc7ac7551492 100644 --- a/src/audio/sndio/SDL_sndioaudio.c +++ b/src/audio/sndio/SDL_sndioaudio.c @@ -108,6 +108,13 @@ static bool load_sndio_syms(void) #ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "audio-libsndio", + "Support for audio through libsndio", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_AUDIO_DRIVER_SNDIO_DYNAMIC +); + static void UnloadSNDIOLibrary(void) { if (sndio_handle) { diff --git a/src/camera/pipewire/SDL_camera_pipewire.c b/src/camera/pipewire/SDL_camera_pipewire.c index 255ea39ac4284..bd90eedb7b11e 100644 --- a/src/camera/pipewire/SDL_camera_pipewire.c +++ b/src/camera/pipewire/SDL_camera_pipewire.c @@ -109,6 +109,13 @@ static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, #ifdef SDL_CAMERA_DRIVER_PIPEWIRE_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "camera-libpipewire", + "Support for camera through libpipewire", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_CAMERA_DRIVER_PIPEWIRE_DYNAMIC +); + static const char *pipewire_library = SDL_CAMERA_DRIVER_PIPEWIRE_DYNAMIC; static SDL_SharedObject *pipewire_handle = NULL; diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index b61a1cd920e6f..b675f1872473f 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -24,12 +24,20 @@ #ifdef SDL_USE_LIBDBUS // we never link directly to libdbus. -static const char *dbus_library = "libdbus-1.so.3"; +#define SDL_DRIVER_DBUS_DYNAMIC "libdbus-1.so.3" +static const char *dbus_library = SDL_DRIVER_DBUS_DYNAMIC; static SDL_SharedObject *dbus_handle = NULL; static char *inhibit_handle = NULL; static unsigned int screensaver_cookie = 0; static SDL_DBusContext dbus; +SDL_ELF_NOTE_DLOPEN( + "core-libdbus", + "Support for D-Bus IPC", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_DRIVER_DBUS_DYNAMIC +); + static bool LoadDBUSSyms(void) { #define SDL_DBUS_SYM2_OPTIONAL(TYPE, x, y) \ diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 907c34c7f662f..3aea729a54b9b 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -36,7 +36,22 @@ #include "SDL_evdev_capabilities.h" #include "../unix/SDL_poll.h" -static const char *SDL_UDEV_LIBS[] = { "libudev.so.1", "libudev.so.0" }; +#define SDL_UDEV_FALLBACK_LIBS "libudev.so.1", "libudev.so.0" + +static const char *SDL_UDEV_LIBS[] = { SDL_UDEV_FALLBACK_LIBS }; + +#ifdef SDL_UDEV_DYNAMIC +#define SDL_UDEV_DLNOTE_LIBS SDL_UDEV_DYNAMIC, SDL_UDEV_FALLBACK_LIBS +#else +#define SDL_UDEV_DLNOTE_LIBS SDL_UDEV_FALLBACK_LIBS +#endif + +SDL_ELF_NOTE_DLOPEN( + "events-udev", + "Support for events through libudev", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_UDEV_DLNOTE_LIBS +); static SDL_UDEV_PrivateData *_this = NULL; diff --git a/src/dynapi/SDL_dynapi_dlopennote.h b/src/dynapi/SDL_dynapi_dlopennote.h new file mode 100644 index 0000000000000..6018dc69cac7e --- /dev/null +++ b/src/dynapi/SDL_dynapi_dlopennote.h @@ -0,0 +1,98 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef SDL_dynapi_dlopennote_h +#define SDL_dynapi_dlopennote_h + +#define SDL_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required" +#define SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended" +#define SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested" + +#if defined(__ELF__) && defined(HAVE_DLOPEN_NOTES) + +#define SDL_ELF_NOTE_DLOPEN_VENDOR "FDO" +#define SDL_ELF_NOTE_DLOPEN_TYPE 0x407c0c0aU + +#define SDL_ELF_NOTE_INTERNAL2(json, variable_name) \ + __attribute__((aligned(4), used, section(".note.dlopen"))) \ + static const struct { \ + struct { \ + Uint32 n_namesz; \ + Uint32 n_descsz; \ + Uint32 n_type; \ + } nhdr; \ + char name[4]; \ + __attribute__((aligned(4))) char dlopen_json[sizeof(json)]; \ + } variable_name = { \ + { \ + sizeof(SDL_ELF_NOTE_DLOPEN_VENDOR), \ + sizeof(json), \ + SDL_ELF_NOTE_DLOPEN_TYPE \ + }, \ + SDL_ELF_NOTE_DLOPEN_VENDOR, \ + json \ + } + +#define SDL_ELF_NOTE_INTERNAL(json, variable_name) \ + SDL_ELF_NOTE_INTERNAL2(json, variable_name) + +#define SDL_SONAME_ARRAY1(N1) "[\"" N1 "\"]" +#define SDL_SONAME_ARRAY2(N1,N2) "[\"" N1 "\",\"" N2 "\"]" +#define SDL_SONAME_ARRAY3(N1,N2,N3) "[\"" N1 "\",\"" N2 "\",\"" N3 "\"]" +#define SDL_SONAME_ARRAY4(N1,N2,N3,N4) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\"]" +#define SDL_SONAME_ARRAY5(N1,N2,N3,N4,N5) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\"]" +#define SDL_SONAME_ARRAY6(N1,N2,N3,N4,N5,N6) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\"]" +#define SDL_SONAME_ARRAY7(N1,N2,N3,N4,N5,N6,N7) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\"]" +#define SDL_SONAME_ARRAY8(N1,N2,N3,N4,N5,N6,N7,N8) "[\"" N1 "\",\"" N2 "\",\"" N3 "\",\"" N4 "\",\"" N5 "\",\"" N6 "\",\"" N7 "\",\"" N8 "\"]" +#define SDL_SONAME_ARRAY_GET(N1,N2,N3,N4,N5,N6,N7,N8,NAME,...) NAME +#define SDL_SONAME_ARRAY(...) \ + SDL_SONAME_ARRAY_GET(__VA_ARGS__, \ + SDL_SONAME_ARRAY8, \ + SDL_SONAME_ARRAY7, \ + SDL_SONAME_ARRAY6, \ + SDL_SONAME_ARRAY5, \ + SDL_SONAME_ARRAY4, \ + SDL_SONAME_ARRAY3, \ + SDL_SONAME_ARRAY2, \ + SDL_SONAME_ARRAY1 \ + )(__VA_ARGS__) + +// Create "unique" variable name using __LINE__, +// so creating elf notes on the same line is not supported +#define SDL_ELF_NOTE_JOIN2(A,B) A##B +#define SDL_ELF_NOTE_JOIN(A,B) SDL_ELF_NOTE_JOIN2(A,B) +#define SDL_ELF_NOTE_UNIQUE_NAME SDL_ELF_NOTE_JOIN(s_dlopen_note_, __LINE__) + +#define SDL_ELF_NOTE_DLOPEN(feature, description, priority, ...) \ + SDL_ELF_NOTE_INTERNAL( \ + "[{\"feature\":\"" feature \ + "\",\"description\":\"" description \ + "\",\"priority\":\"" priority \ + "\",\"soname\":" SDL_SONAME_ARRAY(__VA_ARGS__) "}]", \ + SDL_ELF_NOTE_UNIQUE_NAME) + +#else + +#define SDL_ELF_NOTE_DLOPEN(...) + +#endif + +#endif diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c index a525f22391cc3..07e1577013098 100644 --- a/src/hidapi/SDL_hidapi.c +++ b/src/hidapi/SDL_hidapi.c @@ -40,6 +40,15 @@ #ifndef SDL_HIDAPI_DISABLED +#ifdef SDL_LIBUSB_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "hidabi-libusb", + "Support for joysticks through libusb", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_LIBUSB_DYNAMIC +); +#endif + #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) #include "../core/windows/SDL_windows.h" #endif diff --git a/src/io/io_uring/SDL_asyncio_liburing.c b/src/io/io_uring/SDL_asyncio_liburing.c index 07e8c2415ca13..d9c759798ba5c 100644 --- a/src/io/io_uring/SDL_asyncio_liburing.c +++ b/src/io/io_uring/SDL_asyncio_liburing.c @@ -44,9 +44,17 @@ static bool (*AsyncIOFromFile)(const char *file, const char *mode, SDL_AsyncIO * // we never link directly to liburing. // (this says "-ffi" which sounds like a scripting language binding thing, but the non-ffi version // is static-inline code we can't lookup with dlsym. This is by design.) -static const char *liburing_library = "liburing-ffi.so.2"; +#define SDL_DRIVER_LIBURING_DYNAMIC "liburing-ffi.so.2" +static const char *liburing_library = SDL_DRIVER_LIBURING_DYNAMIC; static void *liburing_handle = NULL; +SDL_ELF_NOTE_DLOPEN( + "io-io_uring", + "Support for async IO through liburing", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_DRIVER_LIBURING_DYNAMIC +); + #define SDL_LIBURING_FUNCS \ SDL_LIBURING_FUNC(int, io_uring_queue_init, (unsigned entries, struct io_uring *ring, unsigned flags)) \ SDL_LIBURING_FUNC(struct io_uring_probe *,io_uring_get_probe,(void)) \ diff --git a/src/storage/steam/SDL_steamstorage.c b/src/storage/steam/SDL_steamstorage.c index 8f735f84df04e..2867bf40fe826 100644 --- a/src/storage/steam/SDL_steamstorage.c +++ b/src/storage/steam/SDL_steamstorage.c @@ -23,6 +23,23 @@ #include "../SDL_sysstorage.h" +#if defined(_WIN64) +#define SDL_DRIVER_STEAMAPI_DYNAMIC "steam_api64.dll" +#elif defined(_WIN32) +#define SDL_DRIVER_STEAMAPI_DYNAMIC "steam_api.dll" +#elif defined(__APPLE__) +#define SDL_DRIVER_STEAMAPI_DYNAMIC "libsteam_api.dylib" +#else +#define SDL_DRIVER_STEAMAPI_DYNAMIC "libsteam_api.so" +#endif + +SDL_ELF_NOTE_DLOPEN( + "storage-steam", + "Support for Steam user storage", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_DRIVER_STEAMAPI_DYNAMIC +); + // !!! FIXME: Async API can use SteamRemoteStorage_ReadFileAsync // !!! FIXME: Async API can use SteamRemoteStorage_WriteFileAsync @@ -154,17 +171,7 @@ static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_Prop return NULL; } - steam->libsteam_api = SDL_LoadObject( -#if defined(_WIN64) - "steam_api64.dll" -#elif defined(_WIN32) - "steam_api.dll" -#elif defined(__APPLE__) - "libsteam_api.dylib" -#else - "libsteam_api.so" -#endif - ); + steam->libsteam_api = SDL_LoadObject(SDL_DRIVER_STEAMAPI_DYNAMIC); if (steam->libsteam_api == NULL) { SDL_free(steam); return NULL; diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 3d4df26073030..4cf7712e31337 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -110,6 +110,37 @@ #define DEFAULT_OGL_ES2 "libGLESv2.so.2" #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1" #define DEFAULT_OGL_ES "libGLESv1_CM.so.1" + +SDL_ELF_NOTE_DLOPEN( + "egl-opengl", + "Support for OpenGL", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_OGL, ALT_OGL +); +SDL_ELF_NOTE_DLOPEN( + "egl-egl", + "Support for EGL", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_EGL +); +SDL_ELF_NOTE_DLOPEN( + "egl-es2", + "Support for EGL ES2", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_OGL_ES2 +); +SDL_ELF_NOTE_DLOPEN( + "egl-es-pvr", + "Support for EGL ES PVR", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_OGL_ES_PVR +); +SDL_ELF_NOTE_DLOPEN( + "egl-ogl-es", + "Support for OpenGL ES", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_OGL_ES +); #endif // SDL_VIDEO_DRIVER_RPI #if defined(SDL_VIDEO_OPENGL) && !defined(SDL_VIDEO_VITA_PVR_OGL) diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.c b/src/video/kmsdrm/SDL_kmsdrmdyn.c index a532ceaf15f1b..af8ffb63245f5 100644 --- a/src/video/kmsdrm/SDL_kmsdrmdyn.c +++ b/src/video/kmsdrm/SDL_kmsdrmdyn.c @@ -29,6 +29,13 @@ #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "video-kmsdrm", + "Support for KMSDRM", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC +); + typedef struct { void *lib; diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/src/video/kmsdrm/SDL_kmsdrmvulkan.c index d58277b789aaa..37a199784148a 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvulkan.c +++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.c @@ -42,6 +42,13 @@ #define DEFAULT_VULKAN "libvulkan.so.1" #endif +SDL_ELF_NOTE_DLOPEN( + "kmsdrm-vulkan", + "Support for Vulkan on KMSDRM", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_VULKAN +); + bool KMSDRM_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path) { VkExtensionProperties *extensions = NULL; diff --git a/src/video/offscreen/SDL_offscreenvulkan.c b/src/video/offscreen/SDL_offscreenvulkan.c index b3dca4acba455..ac1a84f10246d 100644 --- a/src/video/offscreen/SDL_offscreenvulkan.c +++ b/src/video/offscreen/SDL_offscreenvulkan.c @@ -42,6 +42,13 @@ static const char *s_defaultPaths[] = { #endif }; +SDL_ELF_NOTE_DLOPEN( + "offscreen-vulkan", + "Support for offscreen Vulkan", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libvulkan.so.1" +); + #if defined( SDL_PLATFORM_APPLE ) #include diff --git a/src/video/openvr/SDL_openvrvideo.c b/src/video/openvr/SDL_openvrvideo.c index a24cd02fbe9d6..9df1ff267751d 100644 --- a/src/video/openvr/SDL_openvrvideo.c +++ b/src/video/openvr/SDL_openvrvideo.c @@ -53,6 +53,19 @@ struct SDL_GLContextState #include #endif +#ifdef SDL_PLATFORM_WINDOWS +#define SDL_OPENVR_DRIVER_DYNAMIC "openvr_api.dll" +#else +#define SDL_OPENVR_DRIVER_DYNAMIC "openvr_api.so" +#endif + +SDL_ELF_NOTE_DLOPEN( + "video-openvr", + "Support for OpenVR video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_OPENVR_DRIVER_DYNAMIC +); + #define MARKER_ID 0 #define MARKER_STR "vr-marker,frame_end,type,application" @@ -1474,6 +1487,7 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void) { SDL_VideoDevice *device; SDL_VideoData *data; + const char *hint; #ifdef SDL_PLATFORM_WINDOWS SDL_RegisterApp(NULL, 0, NULL); @@ -1495,19 +1509,13 @@ static SDL_VideoDevice *OPENVR_CreateDevice(void) } device->internal = data; - { - const char * hint = SDL_GetHint(SDL_HINT_OPENVR_LIBRARY); - if (hint) - data->openVRLIB = SDL_LoadObject(hint); -#ifdef SDL_PLATFORM_WINDOWS - if (!data->openVRLIB) - data->openVRLIB = SDL_LoadObject("openvr_api.dll"); -#else - if (!data->openVRLIB) - data->openVRLIB = SDL_LoadObject("openvr_api.so"); -#endif + hint = SDL_GetHint(SDL_HINT_OPENVR_LIBRARY); + if (hint) { + data->openVRLIB = SDL_LoadObject(hint); + } + if (!data->openVRLIB) { + data->openVRLIB = SDL_LoadObject(SDL_OPENVR_DRIVER_DYNAMIC); } - if (!data->openVRLIB) { SDL_SetError("Could not open OpenVR API Library"); goto error; diff --git a/src/video/wayland/SDL_waylanddyn.c b/src/video/wayland/SDL_waylanddyn.c index 7d6d42f3f56a9..e45a96fb539ca 100644 --- a/src/video/wayland/SDL_waylanddyn.c +++ b/src/video/wayland/SDL_waylanddyn.c @@ -28,6 +28,45 @@ #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +SDL_ELF_NOTE_DLOPEN( + "wayland", + "Support for Wayland video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +); +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +SDL_ELF_NOTE_DLOPEN( + "wayland", + "Support for Wayland video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +); +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +SDL_ELF_NOTE_DLOPEN( + "wayland", + "Support for Wayland video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +); +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +SDL_ELF_NOTE_DLOPEN( + "wayland", + "Support for Wayland video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +); +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +SDL_ELF_NOTE_DLOPEN( + "wayland", + "Support for Wayland video", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR +); +#endif + typedef struct { SDL_SharedObject *lib; diff --git a/src/video/wayland/SDL_waylandvulkan.c b/src/video/wayland/SDL_waylandvulkan.c index 956be4630e0dd..2f9576d4c027f 100644 --- a/src/video/wayland/SDL_waylandvulkan.c +++ b/src/video/wayland/SDL_waylandvulkan.c @@ -41,6 +41,13 @@ #define DEFAULT_VULKAN "libvulkan.so.1" #endif +SDL_ELF_NOTE_DLOPEN( + "wayland-vulkan", + "Support for Vulkan on wayland backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_VULKAN +); + bool Wayland_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path) { VkExtensionProperties *extensions = NULL; diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index 116f5655e8b61..efab3f72b4bf6 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -38,25 +38,87 @@ typedef struct const char *libname; } x11dynlib; -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC +); + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XTEST + +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC_XTEST +SDL_ELF_NOTE_DLOPEN( + "x11", + "Support for video through X11 backend", + SDL_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + SDL_VIDEO_DRIVER_X11_DYNAMIC_XTEST +); +#else #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XTEST NULL #endif diff --git a/src/video/x11/SDL_x11vulkan.c b/src/video/x11/SDL_x11vulkan.c index 065549b86bbc1..c6851fe080249 100644 --- a/src/video/x11/SDL_x11vulkan.c +++ b/src/video/x11/SDL_x11vulkan.c @@ -39,6 +39,20 @@ #define DEFAULT_X11_XCB "libX11-xcb.so.1" #endif +SDL_ELF_NOTE_DLOPEN( + "x11-vulkan", + "Support for vulkan on X11", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_VULKAN +); + +SDL_ELF_NOTE_DLOPEN( + "x11-vulkan", + "Support for vulkan on X11", + SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + DEFAULT_X11_XCB +); + /* typedef uint32_t xcb_window_t; typedef uint32_t xcb_visualid_t;