mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-08-24 02:34:23 -05:00
libobs,libobs-opengl: Add gs_sync_t
This change adds a new type named gs_sync_t and related functions to X11 and Wayland EGL backends to abstract DRM syncobjs and their various uses. Signed-off-by: Doğukan Korkmaztürk <dkorkmazturk@nvidia.com>
This commit is contained in:
committed by
Ryan Foster
parent
b30b8565aa
commit
68ca91b21d
@@ -1082,6 +1082,91 @@ Texture Functions
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: bool gs_query_sync_capabilities(void)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Checks if the use of synchronization objects is supported
|
||||
|
||||
:rtype: bool
|
||||
:return: *true* if supported, *false* otherwise
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: gs_sync_t *gs_sync_create(void)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Creates a synchronization object
|
||||
|
||||
Inserts a fence command into the command stream of the bound context and
|
||||
creates a synchronization object that is signalled when all the commands
|
||||
preceding the inserted fence are executed.
|
||||
|
||||
:rtype: gs_sync_t*
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: gs_sync_t *gs_sync_create_from_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Creates a synchronization object
|
||||
|
||||
Creates a synchronization object that is signalled when the specified
|
||||
timeline point of the given DRM syncobj is signalled.
|
||||
|
||||
:param syncobj_fd: A file descriptor that is referencing a DRM syncobj
|
||||
:param timeline_point: Timeline point of the DRM syncobj
|
||||
:rtype: gs_sync_t*
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: void gs_sync_destroy(gs_sync_t *sync)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Destroys a synchronization object
|
||||
|
||||
If the given synchronization object is in use, it will be marked for
|
||||
destruction and will be destroyed later when it is no longer referenced.
|
||||
|
||||
:param sync: Synchronization object
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: bool gs_sync_export_syncobj_timeline_point(gs_sync_t *sync, int syncobj_fd, uint64_t timeline_point)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Exports a synchronization object to a DRM syncobj timeline point
|
||||
|
||||
Creates a DRM syncobj timeline point that is signalled when the given
|
||||
synchronization object is signalled.
|
||||
|
||||
:param sync: Synchronization object
|
||||
:param syncobj_fd: A file descriptor that is referencing a DRM syncobj
|
||||
:param timeline_point: Timeline point of the DRM syncobj
|
||||
:rtype: bool
|
||||
:return: *true* if the synchronization object is exported successfully, *false* otherwise
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: bool gs_sync_signal_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Signals a DRM syncobj timeline point
|
||||
|
||||
:param syncobj_fd: A file descriptor that is referencing a DRM syncobj
|
||||
:param timeline_point: Timeline point of the DRM syncobj
|
||||
:rtype: bool
|
||||
:return: *true* if the timeline point is signalled successfully, *false* otherwise
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: bool gs_sync_wait(gs_sync_t *sync)
|
||||
|
||||
**only Linux, FreeBSD, DragonFly:** Wait for a synchronization object to be signalled
|
||||
|
||||
Blocks the execution of the commands that would be inserted into the command
|
||||
stream of the bound context until the given synchronization object is
|
||||
signalled.
|
||||
|
||||
:param sync: Synchronization object
|
||||
:rtype: bool
|
||||
:return: *true* if successful, *false* otherwise
|
||||
|
||||
---------------------
|
||||
|
||||
.. function:: gs_texture_t *gs_texture_create_from_iosurface(void *iosurf)
|
||||
|
||||
**macOS only:** Creates a texture from an IOSurface.
|
||||
@@ -1586,4 +1671,5 @@ Graphics Types
|
||||
.. type:: struct gs_shader gs_shader_t
|
||||
.. type:: struct gs_shader_param gs_sparam_t
|
||||
.. type:: struct gs_device gs_device_t
|
||||
.. type:: void gs_sync_t
|
||||
.. type:: struct graphics_subsystem graphics_t
|
||||
|
||||
@@ -8,6 +8,7 @@ if(NOT TARGET OBS::glad)
|
||||
endif()
|
||||
|
||||
if(OS_LINUX OR OS_FREEBSD OR OS_OPENBSD)
|
||||
find_package(Libdrm REQUIRED)
|
||||
find_package(X11 REQUIRED)
|
||||
find_package(Xcb REQUIRED xcb)
|
||||
find_package(X11-xcb REQUIRED)
|
||||
@@ -54,6 +55,7 @@ target_link_libraries(
|
||||
OBS::glad
|
||||
"$<$<PLATFORM_ID:Darwin>:$<LINK_LIBRARY:FRAMEWORK,Cocoa.framework>>"
|
||||
"$<$<PLATFORM_ID:Darwin>:$<LINK_LIBRARY:FRAMEWORK,IOSurface.framework>>"
|
||||
$<$<PLATFORM_ID:Linux,FreeBSD,OpenBSD>:Libdrm::Libdrm>
|
||||
$<$<PLATFORM_ID:Linux,FreeBSD,OpenBSD>:xcb::xcb>
|
||||
$<$<PLATFORM_ID:Linux,FreeBSD,OpenBSD>:X11::x11-xcb>
|
||||
$<$<AND:$<PLATFORM_ID:Linux,FreeBSD,OpenBSD>,$<BOOL:${ENABLE_WAYLAND}>>:OpenGL::EGL>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/ioctl.h>
|
||||
#include <xf86drm.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
typedef unsigned int drm_handle_t;
|
||||
|
||||
#else
|
||||
@@ -392,6 +395,95 @@ bool gl_egl_query_dmabuf_modifiers_for_format(EGLDisplay egl_display, uint32_t d
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gl_egl_query_sync_capabilities(int drm_fd)
|
||||
{
|
||||
uint64_t syncobjCap = 0;
|
||||
uint64_t syncobjTimelineCap = 0;
|
||||
|
||||
drmGetCap(drm_fd, DRM_CAP_SYNCOBJ, &syncobjCap);
|
||||
drmGetCap(drm_fd, DRM_CAP_SYNCOBJ_TIMELINE, &syncobjTimelineCap);
|
||||
return syncobjCap && syncobjTimelineCap && (EGL_ANDROID_native_fence_sync > 0);
|
||||
}
|
||||
|
||||
gs_sync_t *gl_egl_create_sync(EGLDisplay egl_display)
|
||||
{
|
||||
gs_sync_t *sync = eglCreateSync(egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
|
||||
glFlush();
|
||||
return sync;
|
||||
}
|
||||
|
||||
gs_sync_t *gl_egl_create_sync_from_syncobj_timeline_point(EGLDisplay egl_display, int drm_fd, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
EGLSync sync;
|
||||
int syncfile_fd = -1;
|
||||
uint32_t syncobj_handle = 0;
|
||||
uint32_t temp_handle = 0;
|
||||
|
||||
drmSyncobjFDToHandle(drm_fd, syncobj_fd, &syncobj_handle);
|
||||
drmSyncobjTimelineWait(drm_fd, &syncobj_handle, &timeline_point, 1, INT64_MAX,
|
||||
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE, NULL);
|
||||
drmSyncobjCreate(drm_fd, 0, &temp_handle);
|
||||
drmSyncobjTransfer(drm_fd, temp_handle, 0, syncobj_handle, timeline_point, 0);
|
||||
drmSyncobjExportSyncFile(drm_fd, temp_handle, &syncfile_fd);
|
||||
drmSyncobjDestroy(drm_fd, temp_handle);
|
||||
drmSyncobjDestroy(drm_fd, syncobj_handle);
|
||||
|
||||
const EGLAttrib attributes[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, syncfile_fd, EGL_NONE};
|
||||
|
||||
sync = eglCreateSync(egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, attributes);
|
||||
if (sync == EGL_NO_SYNC) {
|
||||
blog(LOG_ERROR, "Unable to create an EGLSync object from a syncfile fd");
|
||||
close(syncfile_fd);
|
||||
}
|
||||
|
||||
return sync;
|
||||
}
|
||||
|
||||
bool gl_egl_sync_export_syncobj_timeline_point(EGLDisplay egl_display, gs_sync_t *sync, int drm_fd, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
uint32_t syncobj_handle = 0;
|
||||
uint32_t temp_handle = 0;
|
||||
|
||||
int gs_sync_fd = eglDupNativeFenceFDANDROID(egl_display, sync);
|
||||
if (gs_sync_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
drmSyncobjFDToHandle(drm_fd, syncobj_fd, &syncobj_handle);
|
||||
drmSyncobjCreate(drm_fd, 0, &temp_handle);
|
||||
drmSyncobjImportSyncFile(drm_fd, temp_handle, gs_sync_fd);
|
||||
drmSyncobjTransfer(drm_fd, syncobj_handle, timeline_point, temp_handle, 0, 0);
|
||||
drmSyncobjDestroy(drm_fd, temp_handle);
|
||||
drmSyncobjDestroy(drm_fd, syncobj_handle);
|
||||
close(gs_sync_fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gl_egl_sync_signal_syncobj_timeline_point(int drm_fd, int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
uint32_t syncobj_handle = 0;
|
||||
bool result;
|
||||
|
||||
drmSyncobjFDToHandle(drm_fd, syncobj_fd, &syncobj_handle);
|
||||
result = drmSyncobjTimelineSignal(drm_fd, &syncobj_handle, &timeline_point, 1) == 0;
|
||||
drmSyncobjDestroy(drm_fd, syncobj_handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void gl_egl_device_sync_destroy(EGLDisplay egl_display, gs_sync_t *sync)
|
||||
{
|
||||
eglDestroySync(egl_display, sync);
|
||||
}
|
||||
|
||||
bool gl_egl_sync_wait(EGLDisplay egl_display, gs_sync_t *sync)
|
||||
{
|
||||
return eglWaitSync(egl_display, sync, 0);
|
||||
}
|
||||
|
||||
const char *gl_egl_error_to_string(EGLint error_number)
|
||||
{
|
||||
switch (error_number) {
|
||||
@@ -445,3 +537,26 @@ const char *gl_egl_error_to_string(EGLint error_number)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int get_drm_render_node_fd(EGLDisplay egl_display)
|
||||
{
|
||||
EGLAttrib attrib;
|
||||
EGLDeviceEXT device;
|
||||
const char *drm_render_node_path;
|
||||
|
||||
if (eglQueryDisplayAttribEXT(egl_display, EGL_DEVICE_EXT, &attrib) != EGL_TRUE) {
|
||||
return -1;
|
||||
}
|
||||
device = (EGLDeviceEXT)attrib;
|
||||
drm_render_node_path = eglQueryDeviceStringEXT(device, EGL_DRM_RENDER_NODE_FILE_EXT);
|
||||
if (drm_render_node_path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return open(drm_render_node_path, O_RDWR | O_CLOEXEC);
|
||||
}
|
||||
|
||||
void close_drm_render_node_fd(int fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
const char *gl_egl_error_to_string(EGLint error_number);
|
||||
|
||||
int get_drm_render_node_fd(EGLDisplay egl_display);
|
||||
|
||||
void close_drm_render_node_fd(int fd);
|
||||
|
||||
struct gs_texture *gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width, unsigned int height,
|
||||
uint32_t drm_format, enum gs_color_format color_format, uint32_t n_planes,
|
||||
const int *fds, const uint32_t *strides, const uint32_t *offsets,
|
||||
@@ -24,3 +28,19 @@ struct gs_texture *gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uin
|
||||
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();
|
||||
|
||||
bool gl_egl_query_sync_capabilities(int drm_fd);
|
||||
|
||||
gs_sync_t *gl_egl_create_sync(EGLDisplay egl_display);
|
||||
|
||||
gs_sync_t *gl_egl_create_sync_from_syncobj_timeline_point(EGLDisplay egl_display, int drm_fd, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
void gl_egl_device_sync_destroy(EGLDisplay egl_display, gs_sync_t *sync);
|
||||
|
||||
bool gl_egl_sync_export_syncobj_timeline_point(EGLDisplay egl_display, gs_sync_t *sync, int drm_fd, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
bool gl_egl_sync_signal_syncobj_timeline_point(int drm_fd, int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
bool gl_egl_sync_wait(EGLDisplay egl_display, gs_sync_t *sync);
|
||||
|
||||
@@ -170,3 +170,39 @@ struct gs_texture *device_texture_create_from_pixmap(gs_device_t *device, uint32
|
||||
{
|
||||
return gl_vtable->device_texture_create_from_pixmap(device, width, height, color_format, target, pixmap);
|
||||
}
|
||||
|
||||
bool device_query_sync_capabilities(gs_device_t *device)
|
||||
{
|
||||
return gl_vtable->device_query_sync_capabilities(device);
|
||||
}
|
||||
|
||||
gs_sync_t *device_sync_create(gs_device_t *device)
|
||||
{
|
||||
return gl_vtable->device_sync_create(device);
|
||||
}
|
||||
|
||||
gs_sync_t *device_sync_create_from_syncobj_timeline_point(gs_device_t *device, int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
return gl_vtable->device_sync_create_from_syncobj_timeline_point(device, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
void device_sync_destroy(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
return gl_vtable->device_sync_destroy(device, sync);
|
||||
}
|
||||
|
||||
bool device_sync_export_syncobj_timeline_point(gs_device_t *device, gs_sync_t *sync, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
return gl_vtable->device_sync_export_syncobj_timeline_point(device, sync, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
bool device_sync_signal_syncobj_timeline_point(gs_device_t *device, int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
return gl_vtable->device_sync_signal_syncobj_timeline_point(device, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
bool device_sync_wait(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
return gl_vtable->device_sync_wait(device, sync);
|
||||
}
|
||||
|
||||
@@ -67,4 +67,20 @@ struct gl_winsys_vtable {
|
||||
void *pixmap);
|
||||
bool (*device_enum_adapters)(gs_device_t *device, bool (*callback)(void *param, const char *name, uint32_t id),
|
||||
void *param);
|
||||
|
||||
bool (*device_query_sync_capabilities)(gs_device_t *device);
|
||||
|
||||
gs_sync_t *(*device_sync_create)(gs_device_t *device);
|
||||
|
||||
gs_sync_t *(*device_sync_create_from_syncobj_timeline_point)(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
void (*device_sync_destroy)(gs_device_t *device, gs_sync_t *sync);
|
||||
|
||||
bool (*device_sync_export_syncobj_timeline_point)(gs_device_t *device, gs_sync_t *sync, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
bool (*device_sync_signal_syncobj_timeline_point)(gs_device_t *device, int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
bool (*device_sync_wait)(gs_device_t *device, gs_sync_t *sync);
|
||||
};
|
||||
|
||||
@@ -658,6 +658,8 @@ struct gs_device {
|
||||
struct fbo_info *cur_fbo;
|
||||
};
|
||||
|
||||
typedef void *gs_sync;
|
||||
|
||||
extern struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, uint32_t height);
|
||||
|
||||
extern void gl_update(gs_device_t *device);
|
||||
|
||||
@@ -90,6 +90,8 @@ struct gl_platform {
|
||||
EGLDisplay display;
|
||||
EGLConfig config;
|
||||
EGLContext context;
|
||||
|
||||
int drm_fd;
|
||||
};
|
||||
|
||||
struct gl_windowinfo *gl_wayland_egl_windowinfo_create(const struct gs_init_data *info)
|
||||
@@ -227,6 +229,11 @@ static struct gl_platform *gl_wayland_egl_platform_create(gs_device_t *device, u
|
||||
goto fail_load_egl;
|
||||
}
|
||||
|
||||
plat->drm_fd = get_drm_render_node_fd(plat->display);
|
||||
if (plat->drm_fd < 0) {
|
||||
blog(LOG_WARNING, "Unable to open DRM render node.");
|
||||
}
|
||||
|
||||
goto success;
|
||||
|
||||
fail_load_egl:
|
||||
@@ -247,6 +254,7 @@ static void gl_wayland_egl_platform_destroy(struct gl_platform *plat)
|
||||
if (plat) {
|
||||
egl_context_destroy(plat);
|
||||
eglTerminate(plat->display);
|
||||
close_drm_render_node_fd(plat->drm_fd);
|
||||
bfree(plat);
|
||||
}
|
||||
}
|
||||
@@ -381,6 +389,58 @@ static bool gl_wayland_egl_enum_adapters(gs_device_t *device,
|
||||
return gl_egl_enum_adapters(device->plat->display, callback, param);
|
||||
}
|
||||
|
||||
static bool gl_wayland_egl_device_query_sync_capabilities(gs_device_t *device)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_query_sync_capabilities(plat->drm_fd);
|
||||
}
|
||||
|
||||
static gs_sync_t *gl_wayland_egl_device_sync_create(gs_device_t *device)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_create_sync(plat->display);
|
||||
}
|
||||
|
||||
static gs_sync_t *gl_wayland_egl_device_sync_create_from_syncobj_timeline_point(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_create_sync_from_syncobj_timeline_point(plat->display, plat->drm_fd, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
static void gl_wayland_egl_device_sync_destroy(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
gl_egl_device_sync_destroy(plat->display, sync);
|
||||
}
|
||||
|
||||
static bool gl_wayland_egl_device_sync_export_syncobj_timeline_point(gs_device_t *device, gs_sync_t *sync,
|
||||
int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_export_syncobj_timeline_point(plat->display, sync, plat->drm_fd, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
static bool gl_wayland_egl_device_sync_signal_syncobj_timeline_point(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_signal_syncobj_timeline_point(plat->drm_fd, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
static bool gl_wayland_egl_device_sync_wait(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_wait(plat->display, sync);
|
||||
}
|
||||
|
||||
static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
|
||||
.windowinfo_create = gl_wayland_egl_windowinfo_create,
|
||||
.windowinfo_destroy = gl_wayland_egl_windowinfo_destroy,
|
||||
@@ -401,6 +461,13 @@ static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
|
||||
.device_query_dmabuf_modifiers_for_format = 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,
|
||||
.device_query_sync_capabilities = gl_wayland_egl_device_query_sync_capabilities,
|
||||
.device_sync_create = gl_wayland_egl_device_sync_create,
|
||||
.device_sync_create_from_syncobj_timeline_point = gl_wayland_egl_device_sync_create_from_syncobj_timeline_point,
|
||||
.device_sync_destroy = gl_wayland_egl_device_sync_destroy,
|
||||
.device_sync_export_syncobj_timeline_point = gl_wayland_egl_device_sync_export_syncobj_timeline_point,
|
||||
.device_sync_signal_syncobj_timeline_point = gl_wayland_egl_device_sync_signal_syncobj_timeline_point,
|
||||
.device_sync_wait = gl_wayland_egl_device_sync_wait,
|
||||
};
|
||||
|
||||
const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void)
|
||||
|
||||
@@ -83,6 +83,7 @@ struct gl_platform {
|
||||
EGLContext context;
|
||||
EGLSurface pbuffer;
|
||||
bool close_xdisplay;
|
||||
int drm_fd;
|
||||
};
|
||||
|
||||
/* The following utility function is copied verbatim from GLX code. */
|
||||
@@ -342,6 +343,11 @@ static struct gl_platform *gl_x11_egl_platform_create(gs_device_t *device, uint3
|
||||
goto fail_load_gl;
|
||||
}
|
||||
|
||||
plat->drm_fd = get_drm_render_node_fd(plat->edisplay);
|
||||
if (plat->drm_fd < 0) {
|
||||
blog(LOG_WARNING, "Unable to open DRM render node.");
|
||||
}
|
||||
|
||||
goto success;
|
||||
|
||||
fail_make_current:
|
||||
@@ -367,6 +373,7 @@ static void gl_x11_egl_platform_destroy(struct gl_platform *plat)
|
||||
eglTerminate(plat->edisplay);
|
||||
if (plat->close_xdisplay)
|
||||
XCloseDisplay(plat->xdisplay);
|
||||
close_drm_render_node_fd(plat->drm_fd);
|
||||
bfree(plat);
|
||||
}
|
||||
|
||||
@@ -571,6 +578,59 @@ static bool gl_x11_egl_enum_adapters(gs_device_t *device, bool (*callback)(void
|
||||
return gl_egl_enum_adapters(device->plat->edisplay, callback, param);
|
||||
}
|
||||
|
||||
static bool gl_x11_egl_device_query_sync_capabilities(gs_device_t *device)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_query_sync_capabilities(plat->drm_fd);
|
||||
}
|
||||
|
||||
static gs_sync_t *gl_x11_egl_device_sync_create(gs_device_t *device)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_create_sync(plat->edisplay);
|
||||
}
|
||||
|
||||
static gs_sync_t *gl_x11_egl_device_sync_create_from_syncobj_timeline_point(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_create_sync_from_syncobj_timeline_point(plat->edisplay, plat->drm_fd, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
static void gl_x11_egl_device_sync_destroy(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
gl_egl_device_sync_destroy(plat->edisplay, sync);
|
||||
}
|
||||
|
||||
static bool gl_x11_egl_device_sync_export_syncobj_timeline_point(gs_device_t *device, gs_sync_t *sync, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_export_syncobj_timeline_point(plat->edisplay, sync, plat->drm_fd, syncobj_fd,
|
||||
timeline_point);
|
||||
}
|
||||
|
||||
static bool gl_x11_egl_device_sync_signal_syncobj_timeline_point(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_signal_syncobj_timeline_point(plat->drm_fd, syncobj_fd, timeline_point);
|
||||
}
|
||||
|
||||
static bool gl_x11_egl_device_sync_wait(gs_device_t *device, gs_sync_t *sync)
|
||||
{
|
||||
struct gl_platform *plat = device->plat;
|
||||
|
||||
return gl_egl_sync_wait(plat->edisplay, sync);
|
||||
}
|
||||
|
||||
static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
|
||||
.windowinfo_create = gl_x11_egl_windowinfo_create,
|
||||
.windowinfo_destroy = gl_x11_egl_windowinfo_destroy,
|
||||
@@ -591,6 +651,13 @@ static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
|
||||
.device_query_dmabuf_modifiers_for_format = 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,
|
||||
.device_query_sync_capabilities = gl_x11_egl_device_query_sync_capabilities,
|
||||
.device_sync_create = gl_x11_egl_device_sync_create,
|
||||
.device_sync_create_from_syncobj_timeline_point = gl_x11_egl_device_sync_create_from_syncobj_timeline_point,
|
||||
.device_sync_destroy = gl_x11_egl_device_sync_destroy,
|
||||
.device_sync_export_syncobj_timeline_point = gl_x11_egl_device_sync_export_syncobj_timeline_point,
|
||||
.device_sync_signal_syncobj_timeline_point = gl_x11_egl_device_sync_signal_syncobj_timeline_point,
|
||||
.device_sync_wait = gl_x11_egl_device_sync_wait,
|
||||
};
|
||||
|
||||
const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void)
|
||||
|
||||
@@ -150,6 +150,22 @@ EXPORT bool device_query_dmabuf_modifiers_for_format(gs_device_t *device, uint32
|
||||
EXPORT gs_texture_t *device_texture_create_from_pixmap(gs_device_t *device, uint32_t width, uint32_t height,
|
||||
enum gs_color_format color_format, uint32_t target,
|
||||
void *pixmap);
|
||||
|
||||
EXPORT bool device_query_sync_capabilities(gs_device_t *device);
|
||||
|
||||
EXPORT gs_sync_t *device_sync_create(gs_device_t *device);
|
||||
|
||||
EXPORT gs_sync_t *device_sync_create_from_syncobj_timeline_point(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
EXPORT void device_sync_destroy(gs_device_t *device, gs_sync_t *sync);
|
||||
|
||||
EXPORT bool device_sync_export_syncobj_timeline_point(gs_device_t *device, gs_sync_t *sync, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
|
||||
EXPORT bool device_sync_signal_syncobj_timeline_point(gs_device_t *device, int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
EXPORT bool device_sync_wait(gs_device_t *device, gs_sync_t *sync);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -242,6 +242,13 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, const char
|
||||
GRAPHICS_IMPORT(device_query_dmabuf_capabilities);
|
||||
GRAPHICS_IMPORT(device_query_dmabuf_modifiers_for_format);
|
||||
GRAPHICS_IMPORT(device_texture_create_from_pixmap);
|
||||
GRAPHICS_IMPORT(device_query_sync_capabilities);
|
||||
GRAPHICS_IMPORT(device_sync_create);
|
||||
GRAPHICS_IMPORT(device_sync_create_from_syncobj_timeline_point);
|
||||
GRAPHICS_IMPORT(device_sync_destroy);
|
||||
GRAPHICS_IMPORT(device_sync_export_syncobj_timeline_point);
|
||||
GRAPHICS_IMPORT(device_sync_signal_syncobj_timeline_point);
|
||||
GRAPHICS_IMPORT(device_sync_wait);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
|
||||
@@ -264,6 +264,15 @@ struct gs_exports {
|
||||
struct gs_texture *(*device_texture_create_from_pixmap)(gs_device_t *device, uint32_t width, uint32_t height,
|
||||
enum gs_color_format color_format, uint32_t target,
|
||||
void *pixmap);
|
||||
bool (*device_query_sync_capabilities)(gs_device_t *device);
|
||||
gs_sync_t *(*device_sync_create)(gs_device_t *device);
|
||||
gs_sync_t *(*device_sync_create_from_syncobj_timeline_point)(gs_device_t *device, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
void (*device_sync_destroy)(gs_device_t *device, gs_sync_t *sync);
|
||||
bool (*device_sync_export_syncobj_timeline_point)(gs_device_t *device, gs_sync_t *sync, int syncobj_fd,
|
||||
uint64_t timeline_point);
|
||||
bool (*device_sync_signal_syncobj_timeline_point)(gs_device_t *device, int syncobj_fd, uint64_t timeline_point);
|
||||
bool (*device_sync_wait)(gs_device_t *device, gs_sync_t *sync);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -1371,6 +1371,58 @@ gs_texture_t *gs_texture_create_from_pixmap(uint32_t width, uint32_t height, enu
|
||||
target, pixmap);
|
||||
}
|
||||
|
||||
bool gs_query_sync_capabilities(void)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_query_sync_capabilities(graphics->device);
|
||||
}
|
||||
|
||||
gs_sync_t *gs_sync_create(void)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_create(graphics->device);
|
||||
}
|
||||
|
||||
gs_sync_t *gs_sync_create_from_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_create_from_syncobj_timeline_point(graphics->device, syncobj_fd,
|
||||
timeline_point);
|
||||
}
|
||||
|
||||
void gs_sync_destroy(gs_sync_t *sync)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_destroy(graphics->device, sync);
|
||||
}
|
||||
|
||||
bool gs_sync_export_syncobj_timeline_point(gs_sync_t *sync, int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_export_syncobj_timeline_point(graphics->device, sync, syncobj_fd,
|
||||
timeline_point);
|
||||
}
|
||||
|
||||
bool gs_sync_signal_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_signal_syncobj_timeline_point(graphics->device, syncobj_fd,
|
||||
timeline_point);
|
||||
}
|
||||
|
||||
bool gs_sync_wait(gs_sync_t *sync)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
return graphics->exports.device_sync_wait(graphics->device, sync);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
gs_texture_t *gs_cubetexture_create(uint32_t size, enum gs_color_format color_format, uint32_t levels,
|
||||
|
||||
@@ -299,6 +299,7 @@ typedef struct gs_effect_technique gs_technique_t;
|
||||
typedef struct gs_effect_pass gs_epass_t;
|
||||
typedef struct gs_effect_param gs_eparam_t;
|
||||
typedef struct gs_device gs_device_t;
|
||||
typedef void gs_sync_t;
|
||||
typedef struct graphics_subsystem graphics_t;
|
||||
|
||||
/* ---------------------------------------------------
|
||||
@@ -899,6 +900,19 @@ EXPORT bool gs_query_dmabuf_modifiers_for_format(uint32_t drm_format, uint64_t *
|
||||
EXPORT gs_texture_t *gs_texture_create_from_pixmap(uint32_t width, uint32_t height, enum gs_color_format color_format,
|
||||
uint32_t target, void *pixmap);
|
||||
|
||||
EXPORT bool gs_query_sync_capabilities(void);
|
||||
|
||||
EXPORT gs_sync_t *gs_sync_create(void);
|
||||
|
||||
EXPORT gs_sync_t *gs_sync_create_from_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
EXPORT void gs_sync_destroy(gs_sync_t *sync);
|
||||
|
||||
EXPORT bool gs_sync_export_syncobj_timeline_point(gs_sync_t *sync, int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
EXPORT bool gs_sync_signal_syncobj_timeline_point(int syncobj_fd, uint64_t timeline_point);
|
||||
|
||||
EXPORT bool gs_sync_wait(gs_sync_t *sync);
|
||||
#endif
|
||||
|
||||
/* inline functions used by modules */
|
||||
|
||||
Reference in New Issue
Block a user