Browse Source

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.
Georges Basile Stavracas Neto 5 years ago
parent
commit
f7a55f45fd

+ 11 - 0
libobs-opengl/gl-nix.c

@@ -123,3 +123,14 @@ extern void device_present(gs_device_t *device)
 {
 {
 	gl_vtable->device_present(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);
+}

+ 6 - 0
libobs-opengl/gl-nix.h

@@ -53,4 +53,10 @@ struct gl_winsys_vtable {
 				      gs_swapchain_t *swap);
 				      gs_swapchain_t *swap);
 
 
 	void (*device_present)(gs_device_t *device);
 	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);
 };
 };

+ 21 - 0
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 = {
 static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
 	.windowinfo_create = gl_wayland_egl_windowinfo_create,
 	.windowinfo_create = gl_wayland_egl_windowinfo_create,
 	.windowinfo_destroy = gl_wayland_egl_windowinfo_destroy,
 	.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,
 	.update = gl_wayland_egl_update,
 	.device_load_swapchain = gl_wayland_egl_device_load_swapchain,
 	.device_load_swapchain = gl_wayland_egl_device_load_swapchain,
 	.device_present = gl_wayland_egl_device_present,
 	.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)
 const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void)

+ 21 - 0
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());
 		     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 = {
 static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
 	.windowinfo_create = gl_x11_egl_windowinfo_create,
 	.windowinfo_create = gl_x11_egl_windowinfo_create,
 	.windowinfo_destroy = gl_x11_egl_windowinfo_destroy,
 	.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,
 	.update = gl_x11_egl_update,
 	.device_load_swapchain = gl_x11_egl_device_load_swapchain,
 	.device_load_swapchain = gl_x11_egl_device_load_swapchain,
 	.device_present = gl_x11_egl_device_present,
 	.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)
 const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void)

+ 21 - 0
libobs-opengl/gl-x11-glx.c

@@ -579,6 +579,25 @@ static void gl_x11_glx_device_present(gs_device_t *device)
 	glXSwapBuffers(display, window);
 	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 = {
 static const struct gl_winsys_vtable glx_winsys_vtable = {
 	.windowinfo_create = gl_x11_glx_windowinfo_create,
 	.windowinfo_create = gl_x11_glx_windowinfo_create,
 	.windowinfo_destroy = gl_x11_glx_windowinfo_destroy,
 	.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,
 	.update = gl_x11_glx_update,
 	.device_load_swapchain = gl_x11_glx_device_load_swapchain,
 	.device_load_swapchain = gl_x11_glx_device_load_swapchain,
 	.device_present = gl_x11_glx_device_present,
 	.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)
 const struct gl_winsys_vtable *gl_x11_glx_get_winsys_vtable(void)

+ 10 - 0
libobs/graphics/device-exports.h

@@ -170,6 +170,16 @@ EXPORT void device_debug_marker_begin(gs_device_t *device,
 				      const float color[4]);
 				      const float color[4]);
 EXPORT void device_debug_marker_end(gs_device_t *device);
 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
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 2 - 0
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_stagesurface_create_nv12);
 	GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
 	GRAPHICS_IMPORT_OPTIONAL(device_register_loss_callbacks);
 	GRAPHICS_IMPORT_OPTIONAL(device_unregister_loss_callbacks);
 	GRAPHICS_IMPORT_OPTIONAL(device_unregister_loss_callbacks);
+#elif __linux__
+	GRAPHICS_IMPORT(device_texture_create_from_dmabuf);
 #endif
 #endif
 
 
 	return success;
 	return success;

+ 6 - 0
libobs/graphics/graphics-internal.h

@@ -325,6 +325,12 @@ struct gs_exports {
 		gs_device_t *device, const struct gs_device_loss *callbacks);
 		gs_device_t *device, const struct gs_device_loss *callbacks);
 	void (*device_unregister_loss_callbacks)(gs_device_t *device,
 	void (*device_unregister_loss_callbacks)(gs_device_t *device,
 						 void *data);
 						 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
 #endif
 };
 };
 
 

+ 19 - 0
libobs/graphics/graphics.c

@@ -1363,6 +1363,25 @@ gs_texture_t *gs_texture_create(uint32_t width, uint32_t height,
 						       levels, data, flags);
 						       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,
 gs_texture_t *gs_cubetexture_create(uint32_t size,
 				    enum gs_color_format color_format,
 				    enum gs_color_format color_format,
 				    uint32_t levels, const uint8_t **data,
 				    uint32_t levels, const uint8_t **data,

+ 9 - 0
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_register_loss_callbacks(const struct gs_device_loss *callbacks);
 EXPORT void gs_unregister_loss_callbacks(void *data);
 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
 #endif
 
 
 /* inline functions used by modules */
 /* inline functions used by modules */