From f7a55f45fdacf9c8383cafae8170294ac8997954 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 12 Mar 2020 23:50:18 -0300 Subject: [PATCH] libobs/graphics: Add Linux-only gs_texture_create_from_dmabuf() DMA-BUF is a widespread Linux buffer sharing mechanism. It is what's commonly used zero-copy screen sharing by Wayland compositors. Add a new 'device_texture_create_from_dmabuf' vfunc to gs_exports, and stub implementations to libobs-opengl. Add a new public method gs_texture_create_from_dmabuf() that calls this vfunc. --- libobs-opengl/gl-nix.c | 11 +++++++++++ libobs-opengl/gl-nix.h | 6 ++++++ libobs-opengl/gl-wayland-egl.c | 21 +++++++++++++++++++++ libobs-opengl/gl-x11-egl.c | 21 +++++++++++++++++++++ libobs-opengl/gl-x11-glx.c | 21 +++++++++++++++++++++ libobs/graphics/device-exports.h | 10 ++++++++++ libobs/graphics/graphics-imports.c | 2 ++ libobs/graphics/graphics-internal.h | 6 ++++++ libobs/graphics/graphics.c | 19 +++++++++++++++++++ libobs/graphics/graphics.h | 9 +++++++++ 10 files changed, 126 insertions(+) diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c index 6c272c3d9..acbd154a8 100644 --- a/libobs-opengl/gl-nix.c +++ b/libobs-opengl/gl-nix.c @@ -123,3 +123,14 @@ extern void device_present(gs_device_t *device) { gl_vtable->device_present(device); } + +extern struct gs_texture *device_texture_create_from_dmabuf( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers) +{ + return gl_vtable->device_texture_create_from_dmabuf( + device, width, height, color_format, n_planes, fds, strides, + offsets, modifiers); +} diff --git a/libobs-opengl/gl-nix.h b/libobs-opengl/gl-nix.h index 741154da5..3038c0cff 100644 --- a/libobs-opengl/gl-nix.h +++ b/libobs-opengl/gl-nix.h @@ -53,4 +53,10 @@ struct gl_winsys_vtable { gs_swapchain_t *swap); void (*device_present)(gs_device_t *device); + + struct gs_texture *(*device_texture_create_from_dmabuf)( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, + const int *fds, const uint32_t *strides, + const uint32_t *offsets, const uint64_t *modifiers); }; diff --git a/libobs-opengl/gl-wayland-egl.c b/libobs-opengl/gl-wayland-egl.c index aad6993e8..3968736da 100644 --- a/libobs-opengl/gl-wayland-egl.c +++ b/libobs-opengl/gl-wayland-egl.c @@ -319,6 +319,25 @@ static void gl_wayland_egl_device_present(gs_device_t *device) } } +static struct gs_texture *gl_wayland_egl_device_texture_create_from_dmabuf( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers) +{ + UNUSED_PARAMETER(device); + UNUSED_PARAMETER(width); + UNUSED_PARAMETER(height); + UNUSED_PARAMETER(color_format); + UNUSED_PARAMETER(n_planes); + UNUSED_PARAMETER(fds); + UNUSED_PARAMETER(strides); + UNUSED_PARAMETER(offsets); + UNUSED_PARAMETER(modifiers); + + return NULL; +} + static const struct gl_winsys_vtable egl_wayland_winsys_vtable = { .windowinfo_create = gl_wayland_egl_windowinfo_create, .windowinfo_destroy = gl_wayland_egl_windowinfo_destroy, @@ -334,6 +353,8 @@ static const struct gl_winsys_vtable egl_wayland_winsys_vtable = { .update = gl_wayland_egl_update, .device_load_swapchain = gl_wayland_egl_device_load_swapchain, .device_present = gl_wayland_egl_device_present, + .device_texture_create_from_dmabuf = + gl_wayland_egl_device_texture_create_from_dmabuf, }; const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void) diff --git a/libobs-opengl/gl-x11-egl.c b/libobs-opengl/gl-x11-egl.c index 47b8e420a..7a9c59755 100644 --- a/libobs-opengl/gl-x11-egl.c +++ b/libobs-opengl/gl-x11-egl.c @@ -634,6 +634,25 @@ static void gl_x11_egl_device_present(gs_device_t *device) get_egl_error_string()); } +static struct gs_texture *gl_x11_egl_device_texture_create_from_dmabuf( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers) +{ + UNUSED_PARAMETER(device); + UNUSED_PARAMETER(width); + UNUSED_PARAMETER(height); + UNUSED_PARAMETER(color_format); + UNUSED_PARAMETER(n_planes); + UNUSED_PARAMETER(fds); + UNUSED_PARAMETER(strides); + UNUSED_PARAMETER(offsets); + UNUSED_PARAMETER(modifiers); + + return NULL; +} + static const struct gl_winsys_vtable egl_x11_winsys_vtable = { .windowinfo_create = gl_x11_egl_windowinfo_create, .windowinfo_destroy = gl_x11_egl_windowinfo_destroy, @@ -649,6 +668,8 @@ static const struct gl_winsys_vtable egl_x11_winsys_vtable = { .update = gl_x11_egl_update, .device_load_swapchain = gl_x11_egl_device_load_swapchain, .device_present = gl_x11_egl_device_present, + .device_texture_create_from_dmabuf = + gl_x11_egl_device_texture_create_from_dmabuf, }; const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void) diff --git a/libobs-opengl/gl-x11-glx.c b/libobs-opengl/gl-x11-glx.c index a562b5649..802be3ef9 100644 --- a/libobs-opengl/gl-x11-glx.c +++ b/libobs-opengl/gl-x11-glx.c @@ -579,6 +579,25 @@ static void gl_x11_glx_device_present(gs_device_t *device) glXSwapBuffers(display, window); } +static struct gs_texture *gl_x11_glx_device_texture_create_from_dmabuf( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers) +{ + UNUSED_PARAMETER(device); + UNUSED_PARAMETER(width); + UNUSED_PARAMETER(height); + UNUSED_PARAMETER(color_format); + UNUSED_PARAMETER(n_planes); + UNUSED_PARAMETER(fds); + UNUSED_PARAMETER(strides); + UNUSED_PARAMETER(offsets); + UNUSED_PARAMETER(modifiers); + + return NULL; +} + static const struct gl_winsys_vtable glx_winsys_vtable = { .windowinfo_create = gl_x11_glx_windowinfo_create, .windowinfo_destroy = gl_x11_glx_windowinfo_destroy, @@ -594,6 +613,8 @@ static const struct gl_winsys_vtable glx_winsys_vtable = { .update = gl_x11_glx_update, .device_load_swapchain = gl_x11_glx_device_load_swapchain, .device_present = gl_x11_glx_device_present, + .device_texture_create_from_dmabuf = + gl_x11_glx_device_texture_create_from_dmabuf, }; const struct gl_winsys_vtable *gl_x11_glx_get_winsys_vtable(void) diff --git a/libobs/graphics/device-exports.h b/libobs/graphics/device-exports.h index 0620c6372..ecf7f603e 100644 --- a/libobs/graphics/device-exports.h +++ b/libobs/graphics/device-exports.h @@ -170,6 +170,16 @@ EXPORT void device_debug_marker_begin(gs_device_t *device, const float color[4]); EXPORT void device_debug_marker_end(gs_device_t *device); +#if __linux__ + +EXPORT gs_texture_t *device_texture_create_from_dmabuf( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers); + +#endif + #ifdef __cplusplus } #endif diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index bd4555bb3..62eccb333 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -222,6 +222,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12); GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks); GRAPHICS_IMPORT_OPTIONAL(device_unregister_loss_callbacks); +#elif __linux__ + GRAPHICS_IMPORT(device_texture_create_from_dmabuf); #endif return success; diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index 5b3f29bac..c249dc0c0 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -325,6 +325,12 @@ struct gs_exports { gs_device_t *device, const struct gs_device_loss *callbacks); void (*device_unregister_loss_callbacks)(gs_device_t *device, void *data); +#elif __linux__ + struct gs_texture *(*device_texture_create_from_dmabuf)( + gs_device_t *device, unsigned int width, unsigned int height, + enum gs_color_format color_format, uint32_t n_planes, + const int *fds, const uint32_t *strides, + const uint32_t *offsets, const uint64_t *modifiers); #endif }; diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index bc8c436d1..b23a74a4a 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -1363,6 +1363,25 @@ gs_texture_t *gs_texture_create(uint32_t width, uint32_t height, levels, data, flags); } +#if __linux__ + +gs_texture_t *gs_texture_create_from_dmabuf(unsigned int width, + unsigned int height, + enum gs_color_format color_format, + uint32_t n_planes, const int *fds, + const uint32_t *strides, + const uint32_t *offsets, + const uint64_t *modifiers) +{ + graphics_t *graphics = thread_graphics; + + return graphics->exports.device_texture_create_from_dmabuf( + graphics->device, width, height, color_format, n_planes, fds, + strides, offsets, modifiers); +} + +#endif + gs_texture_t *gs_cubetexture_create(uint32_t size, enum gs_color_format color_format, uint32_t levels, const uint8_t **data, diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index f461d0a15..b254e4394 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -913,6 +913,15 @@ EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, EXPORT void gs_register_loss_callbacks(const struct gs_device_loss *callbacks); EXPORT void gs_unregister_loss_callbacks(void *data); +#elif __linux__ + +EXPORT gs_texture_t * +gs_texture_create_from_dmabuf(unsigned int width, unsigned int height, + enum gs_color_format color_format, + uint32_t n_planes, const int *fds, + const uint32_t *strides, const uint32_t *offsets, + const uint64_t *modifiers); + #endif /* inline functions used by modules */ -- GitLab