From d501f6db07d4a067f7261d1ef51bec199f6d421f Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 2 Sep 2024 08:40:53 -0700
Subject: [PATCH] Make newer DRM and GBM functions optional
Fixes https://github.com/libsdl-org/SDL/issues/10675
---
src/video/kmsdrm/SDL_kmsdrmdyn.c | 32 ++++++++++++----------
src/video/kmsdrm/SDL_kmsdrmdyn.h | 3 +++
src/video/kmsdrm/SDL_kmsdrmsym.h | 19 ++++++++-----
src/video/kmsdrm/SDL_kmsdrmvideo.c | 43 ++++++++++++++++++------------
4 files changed, 59 insertions(+), 38 deletions(-)
diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.c b/src/video/kmsdrm/SDL_kmsdrmdyn.c
index 0ffe3fb576cd6..1a680eac2fd9c 100644
--- a/src/video/kmsdrm/SDL_kmsdrmdyn.c
+++ b/src/video/kmsdrm/SDL_kmsdrmdyn.c
@@ -44,7 +44,7 @@ static kmsdrmdynlib kmsdrmlibs[] = {
{ NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC }
};
-static void *KMSDRM_GetSym(const char *fnname, int *pHasModule)
+static void *KMSDRM_GetSym(const char *fnname, int *pHasModule, bool required)
{
int i;
void *fn = NULL;
@@ -64,7 +64,7 @@ static void *KMSDRM_GetSym(const char *fnname, int *pHasModule)
SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname);
#endif
- if (!fn) {
+ if (!fn && required) {
*pHasModule = 0; // kill this module.
}
@@ -74,9 +74,10 @@ static void *KMSDRM_GetSym(const char *fnname, int *pHasModule)
#endif // SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
// Define all the function pointers and wrappers...
-#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0;
-#define SDL_KMSDRM_SYM(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
-#define SDL_KMSDRM_SYM_CONST(type, name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL;
+#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type, name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL;
+#define SDL_KMSDRM_SYM_OPT(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL;
#include "SDL_kmsdrmsym.h"
static int kmsdrm_load_refcount = 0;
@@ -91,9 +92,10 @@ void SDL_KMSDRM_UnloadSymbols(void)
#endif
// set all the function pointers to NULL.
-#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0;
-#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = NULL;
-#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = NULL;
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0;
+#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = NULL;
+#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = NULL;
+#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = NULL;
#include "SDL_kmsdrmsym.h"
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
@@ -127,9 +129,10 @@ bool SDL_KMSDRM_LoadSymbols(void)
#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; // default yes
#include "SDL_kmsdrmsym.h"
-#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname;
-#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod);
-#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod);
+#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname;
+#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, true);
+#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod, true);
+#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, false);
#include "SDL_kmsdrmsym.h"
if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) {
@@ -143,9 +146,10 @@ bool SDL_KMSDRM_LoadSymbols(void)
#else // no dynamic KMSDRM
-#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; // default yes
-#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = fn;
-#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = name;
+#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; // default yes
+#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = fn;
+#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = name;
+#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = fn;
#include "SDL_kmsdrmsym.h"
#endif
diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.h b/src/video/kmsdrm/SDL_kmsdrmdyn.h
index fb1fc0e580b7d..704671d37e7f6 100644
--- a/src/video/kmsdrm/SDL_kmsdrmdyn.h
+++ b/src/video/kmsdrm/SDL_kmsdrmdyn.h
@@ -42,6 +42,9 @@ extern void SDL_KMSDRM_UnloadSymbols(void);
#define SDL_KMSDRM_SYM_CONST(type, name) \
typedef type SDL_DYNKMSDRMCONST_##name; \
extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name;
+#define SDL_KMSDRM_SYM_OPT(rc, fn, params) \
+ typedef rc(*SDL_DYNKMSDRMFN_##fn) params; \
+ extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn;
#include "SDL_kmsdrmsym.h"
#ifdef __cplusplus
diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h
index e612583ce5581..1f0646636ebcd 100644
--- a/src/video/kmsdrm/SDL_kmsdrmsym.h
+++ b/src/video/kmsdrm/SDL_kmsdrmsym.h
@@ -33,6 +33,10 @@
#define SDL_KMSDRM_SYM_CONST(type, name)
#endif
+#ifndef SDL_KMSDRM_SYM_OPT
+#define SDL_KMSDRM_SYM_OPT(rc,fn,params)
+#endif
+
SDL_KMSDRM_MODULE(LIBDRM)
SDL_KMSDRM_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
@@ -49,12 +53,12 @@ SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id))
-SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height,
+SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height,
uint32_t pixel_format, const uint32_t bo_handles[4],
const uint32_t pitches[4], const uint32_t offsets[4],
uint32_t *buf_id, uint32_t flags))
-SDL_KMSDRM_SYM(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width,
+SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width,
uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
const uint32_t pitches[4], const uint32_t offsets[4],
const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags))
@@ -125,14 +129,15 @@ SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
-SDL_KMSDRM_SYM(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo))
-SDL_KMSDRM_SYM(int,gbm_bo_get_plane_count,(struct gbm_bo *bo))
-SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane))
-SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane))
-SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle_for_plane,(struct gbm_bo *bo, int plane);)
+SDL_KMSDRM_SYM_OPT(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM_OPT(int,gbm_bo_get_plane_count,(struct gbm_bo *bo))
+SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane))
+SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane))
+SDL_KMSDRM_SYM_OPT(union gbm_bo_handle,gbm_bo_get_handle_for_plane,(struct gbm_bo *bo, int plane))
#undef SDL_KMSDRM_MODULE
#undef SDL_KMSDRM_SYM
#undef SDL_KMSDRM_SYM_CONST
+#undef SDL_KMSDRM_SYM_OPT
/* *INDENT-ON* */ // clang-format on
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index d57d5ee6afaae..dbc5bd4af264d 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -348,8 +348,9 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(SDL_VideoDevice *_this, struct gbm_bo *bo)
{
SDL_VideoData *viddata = _this->internal;
unsigned w, h;
- int ret, num_planes = 0;
- Uint32 format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0;
+ int rc = -1;
+ int num_planes = 0;
+ uint32_t format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0;
uint64_t modifiers[4] = { 0 };
// Check for an existing framebuffer
@@ -375,28 +376,36 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(SDL_VideoDevice *_this, struct gbm_bo *bo)
h = KMSDRM_gbm_bo_get_height(bo);
format = KMSDRM_gbm_bo_get_format(bo);
- modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo);
- num_planes = KMSDRM_gbm_bo_get_plane_count(bo);
- for (int i = 0; i < num_planes; i++) {
- strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i);
- handles[i] = KMSDRM_gbm_bo_get_handle_for_plane(bo, i).u32;
- offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i);
- modifiers[i] = modifiers[0];
- }
+ if (KMSDRM_drmModeAddFB2WithModifiers &&
+ KMSDRM_gbm_bo_get_modifier &&
+ KMSDRM_gbm_bo_get_plane_count &&
+ KMSDRM_gbm_bo_get_offset &&
+ KMSDRM_gbm_bo_get_stride_for_plane &&
+ KMSDRM_gbm_bo_get_handle_for_plane) {
+
+ modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo);
+ num_planes = KMSDRM_gbm_bo_get_plane_count(bo);
+ for (int i = 0; i < num_planes; i++) {
+ strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i);
+ handles[i] = KMSDRM_gbm_bo_get_handle_for_plane(bo, i).u32;
+ offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i);
+ modifiers[i] = modifiers[0];
+ }
- if (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID) {
- flags = DRM_MODE_FB_MODIFIERS;
- }
+ if (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID) {
+ flags = DRM_MODE_FB_MODIFIERS;
+ }
- ret = KMSDRM_drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags);
+ rc = KMSDRM_drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags);
+ }
- if (ret) {
+ if (rc < 0) {
strides[0] = KMSDRM_gbm_bo_get_stride(bo);
handles[0] = KMSDRM_gbm_bo_get_handle(bo).u32;
- ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, strides[0], handles[0], &fb_info->fb_id);
+ rc = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, strides[0], handles[0], &fb_info->fb_id);
}
- if (ret) {
+ if (rc < 0) {
SDL_free(fb_info);
return NULL;
}