wlroots/render/dmabuf.c
Kurt Kartaltepe 5cc737d599 render,types/wlr_shm: Offload slow cleanup ops
Defers close()/munmap() calls into a cleanup thread in to avoid blocking
when they are slow. This is most noticable on low end hardware with
large screens where large surfaces can spend considerable time
invalidating mmus on the gpu or clearing shmem pages.
2024-07-27 13:18:26 -07:00

53 lines
1.2 KiB
C

#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <wlr/render/dmabuf.h>
#include <wlr/util/log.h>
#include "render/dmabuf.h"
#include "util/cleanup.h"
static void defer_close_dmabuf(void *data) {
struct wlr_dmabuf_attributes *attribs = data;
for (int i = 0; i < attribs->n_planes; ++i) {
close(attribs->fd[i]);
}
free(attribs);
}
void wlr_dmabuf_attributes_finish(struct wlr_dmabuf_attributes *attribs) {
struct wlr_dmabuf_attributes *attribs_defer = calloc(1, sizeof(struct wlr_dmabuf_attributes));
attribs_defer->n_planes = attribs->n_planes;
for (int i = 0; i < attribs->n_planes; ++i) {
attribs_defer->fd[i] = attribs->fd[i];
attribs->fd[i] = -1;
}
attribs->n_planes = 0;
wlr_cleanup_defer((struct wlr_task){&defer_close_dmabuf, attribs_defer});
}
bool wlr_dmabuf_attributes_copy(struct wlr_dmabuf_attributes *dst,
const struct wlr_dmabuf_attributes *src) {
*dst = *src;
int i;
for (i = 0; i < src->n_planes; ++i) {
dst->fd[i] = fcntl(src->fd[i], F_DUPFD_CLOEXEC, 0);
if (dst->fd[i] < 0) {
wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed");
goto error;
}
}
return true;
error:
for (int j = 0; j < i; j++) {
close(dst->fd[j]);
dst->fd[j] = -1;
}
dst->n_planes = 0;
return false;
}