mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-06-30 16:43:31 +00:00
libobs,libobs-opengl,libobs-d3d11: Add opengl gs_enum_adapters
This adds gs_enum_adapters and gs_get_adapter_count to the opengl backend and promotes these to multiplatform graphics functions. However we need to make an internal device change, device_enum_adapters must pass in the current device on opengl to ensure that adapter #0 is the display adapter. We do this to avoid changes to plugins already checking against obs_video_info.adapter which is always 0 and expected to be the device OBS was initialized on. The actual implementation reports the dri render node (or /Software). This allows plugins to query non-video features of the adapters like VA-API/NVENC/etc or other cross device functionality. `/Software` is chosen to avoid opening random files in the current directory if its passed along as a file path like the regular dri render nodes.
This commit is contained in:
parent
477c3be050
commit
3e49e89611
|
@ -1016,10 +1016,13 @@ EnumD3DAdapters(bool (*callback)(void *, const char *, uint32_t), void *param)
|
|||
}
|
||||
}
|
||||
|
||||
bool device_enum_adapters(bool (*callback)(void *param, const char *name,
|
||||
bool device_enum_adapters(gs_device_t *device,
|
||||
bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param)
|
||||
{
|
||||
UNUSED_PARAMETER(device);
|
||||
|
||||
try {
|
||||
EnumD3DAdapters(callback, param);
|
||||
return true;
|
||||
|
|
|
@ -204,6 +204,53 @@ struct gs_texture *gl_egl_create_texture_from_eglimage(
|
|||
return texture;
|
||||
}
|
||||
|
||||
bool gl_egl_enum_adapters(EGLDisplay display,
|
||||
bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param)
|
||||
{
|
||||
EGLDeviceEXT display_dev;
|
||||
if (eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT,
|
||||
(EGLAttrib *)&display_dev) &&
|
||||
eglGetError() == EGL_SUCCESS) {
|
||||
const char *display_node = eglQueryDeviceStringEXT(
|
||||
display_dev, EGL_DRM_RENDER_NODE_FILE_EXT);
|
||||
if (eglGetError() != EGL_SUCCESS || display_node == NULL) {
|
||||
display_node = "/Software";
|
||||
}
|
||||
if (!callback(param, display_node, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
EGLint num_devices = 0;
|
||||
EGLDeviceEXT devices[32];
|
||||
if (!eglQueryDevicesEXT(32, devices, &num_devices)) {
|
||||
eglGetError();
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_devices; i++) {
|
||||
const char *node = eglQueryDeviceStringEXT(
|
||||
devices[i], EGL_DRM_RENDER_NODE_FILE_EXT);
|
||||
if (node == NULL || eglGetError() != EGL_SUCCESS) {
|
||||
// Do not enumerate additional software renderers.
|
||||
continue;
|
||||
}
|
||||
if (!callback(param, node, i + 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t gs_get_adapter_count()
|
||||
{
|
||||
EGLint num_devices = 0;
|
||||
eglQueryDevicesEXT(0, NULL, &num_devices);
|
||||
return 1 + num_devices; // Display + devices.
|
||||
}
|
||||
|
||||
struct gs_texture *
|
||||
gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width,
|
||||
unsigned int height, uint32_t drm_format,
|
||||
|
|
|
@ -27,3 +27,9 @@ gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uint32_t width,
|
|||
uint32_t height,
|
||||
enum gs_color_format color_format,
|
||||
EGLint target, EGLClientBuffer pixmap);
|
||||
|
||||
bool gl_egl_enum_adapters(EGLDisplay display,
|
||||
bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param);
|
||||
uint32_t gs_get_adapter_count();
|
||||
|
|
|
@ -95,6 +95,14 @@ extern void device_leave_context(gs_device_t *device)
|
|||
gl_vtable->device_leave_context(device);
|
||||
}
|
||||
|
||||
extern bool device_enum_adapters(gs_device_t *device,
|
||||
bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param)
|
||||
{
|
||||
return gl_vtable->device_enum_adapters(device, callback, param);
|
||||
}
|
||||
|
||||
extern void *device_get_device_obj(gs_device_t *device)
|
||||
{
|
||||
return gl_vtable->device_get_device_obj(device);
|
||||
|
|
|
@ -73,4 +73,9 @@ struct gl_winsys_vtable {
|
|||
gs_device_t *device, uint32_t width, uint32_t height,
|
||||
enum gs_color_format color_format, uint32_t target,
|
||||
void *pixmap);
|
||||
bool (*device_enum_adapters)(gs_device_t *device,
|
||||
bool (*callback)(void *param,
|
||||
const char *name,
|
||||
uint32_t id),
|
||||
void *param);
|
||||
};
|
||||
|
|
|
@ -397,6 +397,15 @@ static struct gs_texture *gl_wayland_egl_device_texture_create_from_pixmap(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool gl_wayland_egl_enum_adapters(gs_device_t *device,
|
||||
bool (*callback)(void *param,
|
||||
const char *name,
|
||||
uint32_t id),
|
||||
void *param)
|
||||
{
|
||||
return gl_egl_enum_adapters(device->plat->display, callback, param);
|
||||
}
|
||||
|
||||
static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
|
||||
.windowinfo_create = gl_wayland_egl_windowinfo_create,
|
||||
.windowinfo_destroy = gl_wayland_egl_windowinfo_destroy,
|
||||
|
@ -420,6 +429,7 @@ static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
|
|||
gl_wayland_egl_device_query_dmabuf_modifiers_for_format,
|
||||
.device_texture_create_from_pixmap =
|
||||
gl_wayland_egl_device_texture_create_from_pixmap,
|
||||
.device_enum_adapters = gl_wayland_egl_enum_adapters,
|
||||
};
|
||||
|
||||
const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void)
|
||||
|
|
|
@ -612,6 +612,15 @@ static bool gl_x11_egl_device_query_dmabuf_modifiers_for_format(
|
|||
plat->edisplay, drm_format, modifiers, n_modifiers);
|
||||
}
|
||||
|
||||
static bool gl_x11_egl_enum_adapters(gs_device_t *device,
|
||||
bool (*callback)(void *param,
|
||||
const char *name,
|
||||
uint32_t id),
|
||||
void *param)
|
||||
{
|
||||
return gl_egl_enum_adapters(device->plat->edisplay, callback, param);
|
||||
}
|
||||
|
||||
static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
|
||||
.windowinfo_create = gl_x11_egl_windowinfo_create,
|
||||
.windowinfo_destroy = gl_x11_egl_windowinfo_destroy,
|
||||
|
@ -635,6 +644,7 @@ static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
|
|||
gl_x11_egl_device_query_dmabuf_modifiers_for_format,
|
||||
.device_texture_create_from_pixmap =
|
||||
gl_x11_egl_device_texture_create_from_pixmap,
|
||||
.device_enum_adapters = gl_x11_egl_enum_adapters,
|
||||
};
|
||||
|
||||
const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void)
|
||||
|
|
|
@ -25,7 +25,8 @@ extern "C" {
|
|||
|
||||
EXPORT const char *device_get_name(void);
|
||||
EXPORT int device_get_type(void);
|
||||
EXPORT bool device_enum_adapters(bool (*callback)(void *param, const char *name,
|
||||
EXPORT bool device_enum_adapters(gs_device_t *device,
|
||||
bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param);
|
||||
EXPORT const char *device_preprocessor_name(void);
|
||||
|
|
|
@ -203,6 +203,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||
GRAPHICS_IMPORT(device_debug_marker_begin);
|
||||
GRAPHICS_IMPORT(device_debug_marker_end);
|
||||
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_get_adapter_count);
|
||||
|
||||
/* OSX/Cocoa specific functions */
|
||||
#ifdef __APPLE__
|
||||
GRAPHICS_IMPORT(device_shared_texture_available);
|
||||
|
@ -222,7 +224,6 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
|||
GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_texture);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_color_space);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_duplicator_get_sdr_white_level);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_get_adapter_count);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_can_adapter_fast_clear);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_gdi);
|
||||
GRAPHICS_IMPORT_OPTIONAL(gs_texture_get_dc);
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
struct gs_exports {
|
||||
const char *(*device_get_name)(void);
|
||||
int (*device_get_type)(void);
|
||||
bool (*device_enum_adapters)(bool (*callback)(void *, const char *,
|
||||
bool (*device_enum_adapters)(gs_device_t *device,
|
||||
bool (*callback)(void *, const char *,
|
||||
uint32_t),
|
||||
void *);
|
||||
const char *(*device_preprocessor_name)(void);
|
||||
|
@ -291,6 +292,8 @@ struct gs_exports {
|
|||
const float color[4]);
|
||||
void (*device_debug_marker_end)(gs_device_t *device);
|
||||
|
||||
uint32_t (*gs_get_adapter_count)(void);
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* OSX/Cocoa specific functions */
|
||||
gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev,
|
||||
|
@ -321,7 +324,6 @@ struct gs_exports {
|
|||
gs_duplicator_t *duplicator);
|
||||
float (*gs_duplicator_get_sdr_white_level)(gs_duplicator_t *duplicator);
|
||||
|
||||
uint32_t (*gs_get_adapter_count)(void);
|
||||
bool (*device_can_adapter_fast_clear)(gs_device_t *device);
|
||||
|
||||
gs_texture_t *(*device_texture_create_gdi)(gs_device_t *device,
|
||||
|
|
|
@ -82,7 +82,8 @@ void gs_enum_adapters(bool (*callback)(void *param, const char *name,
|
|||
return;
|
||||
|
||||
if (graphics->exports.device_enum_adapters) {
|
||||
if (graphics->exports.device_enum_adapters(callback, param)) {
|
||||
if (graphics->exports.device_enum_adapters(graphics->device,
|
||||
callback, param)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2986,6 +2987,16 @@ bool gs_texture_create_p010(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t gs_get_adapter_count(void)
|
||||
{
|
||||
if (!gs_valid("gs_get_adapter_count"))
|
||||
return 0;
|
||||
if (!thread_graphics->exports.gs_get_adapter_count)
|
||||
return 0;
|
||||
|
||||
return thread_graphics->exports.gs_get_adapter_count();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
/** Platform specific functions */
|
||||
|
@ -3108,16 +3119,6 @@ bool gs_duplicator_update_frame(gs_duplicator_t *duplicator)
|
|||
return thread_graphics->exports.gs_duplicator_update_frame(duplicator);
|
||||
}
|
||||
|
||||
uint32_t gs_get_adapter_count(void)
|
||||
{
|
||||
if (!gs_valid("gs_get_adapter_count"))
|
||||
return 0;
|
||||
if (!thread_graphics->exports.gs_get_adapter_count)
|
||||
return 0;
|
||||
|
||||
return thread_graphics->exports.gs_get_adapter_count();
|
||||
}
|
||||
|
||||
bool gs_can_adapter_fast_clear(void)
|
||||
{
|
||||
if (!gs_valid("gs_can_adapter_fast_clear"))
|
||||
|
|
|
@ -525,6 +525,7 @@ struct gs_init_data {
|
|||
|
||||
EXPORT const char *gs_get_device_name(void);
|
||||
EXPORT int gs_get_device_type(void);
|
||||
EXPORT uint32_t gs_get_adapter_count(void);
|
||||
EXPORT void gs_enum_adapters(bool (*callback)(void *param, const char *name,
|
||||
uint32_t id),
|
||||
void *param);
|
||||
|
@ -929,7 +930,6 @@ EXPORT enum gs_color_space
|
|||
gs_duplicator_get_color_space(gs_duplicator_t *duplicator);
|
||||
EXPORT float gs_duplicator_get_sdr_white_level(gs_duplicator_t *duplicator);
|
||||
|
||||
EXPORT uint32_t gs_get_adapter_count(void);
|
||||
EXPORT bool gs_can_adapter_fast_clear(void);
|
||||
|
||||
/** creates a windows GDI-lockable texture */
|
||||
|
|
Loading…
Reference in a new issue