mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-08 13:29:45 -05:00
render/timeline: introduce wlr_timeline
wlr_timeline is a synchronization primitive based on drm_syncobj timelines. They are heavily inspired from Vulkan timeline semaphores [1]. [1]: https://www.khronos.org/blog/vulkan-timeline-semaphores
This commit is contained in:
parent
2a1d7d40f4
commit
bfc616fc7e
3 changed files with 147 additions and 0 deletions
86
render/timeline.c
Normal file
86
render/timeline.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include <xf86drm.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/render/timeline.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
struct wlr_render_timeline {
|
||||
int drm_fd;
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
struct wlr_render_timeline *wlr_render_timeline_create(int drm_fd) {
|
||||
struct wlr_render_timeline *timeline = calloc(1, sizeof(*timeline));
|
||||
if (timeline == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
timeline->drm_fd = drm_fd;
|
||||
|
||||
if (drmSyncobjCreate(drm_fd, 0, &timeline->handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjCreate failed");
|
||||
free(timeline);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return timeline;
|
||||
}
|
||||
|
||||
void wlr_render_timeline_destroy(struct wlr_render_timeline *timeline) {
|
||||
drmSyncobjDestroy(timeline->drm_fd, timeline->handle);
|
||||
free(timeline);
|
||||
}
|
||||
|
||||
int wlr_render_timeline_export_sync_file(struct wlr_render_timeline *timeline,
|
||||
uint64_t src_point) {
|
||||
int sync_file_fd = -1;
|
||||
|
||||
uint32_t syncobj_handle;
|
||||
if (drmSyncobjCreate(timeline->drm_fd, 0, &syncobj_handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjCreate failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (drmSyncobjTransfer(timeline->drm_fd, syncobj_handle, 0,
|
||||
timeline->handle, src_point, 0) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjTransfer failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (drmSyncobjExportSyncFile(timeline->drm_fd,
|
||||
syncobj_handle, &sync_file_fd) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjExportSyncFile failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
drmSyncobjDestroy(timeline->drm_fd, syncobj_handle);
|
||||
return sync_file_fd;
|
||||
}
|
||||
|
||||
bool wlr_render_timeline_import_sync_file(struct wlr_render_timeline *timeline,
|
||||
uint64_t dst_point, int sync_file_fd) {
|
||||
bool ok = false;
|
||||
|
||||
uint32_t syncobj_handle;
|
||||
if (drmSyncobjCreate(timeline->drm_fd, 0, &syncobj_handle) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjCreate failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (drmSyncobjImportSyncFile(timeline->drm_fd, syncobj_handle,
|
||||
sync_file_fd) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjImportSyncFile failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (drmSyncobjTransfer(timeline->drm_fd, timeline->handle, dst_point,
|
||||
syncobj_handle, 0, 0) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "drmSyncobjTransfer failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
||||
out:
|
||||
drmSyncobjDestroy(timeline->drm_fd, syncobj_handle);
|
||||
return ok;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue