/*
 * Virtio vhost-user GPU Device
 *
 * DRM helpers
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "vugbm.h"

static bool
mem_alloc_bo(struct vugbm_buffer *buf)
{
    buf->mmap = g_malloc(buf->width * buf->height * 4);
    buf->stride = buf->width * 4;
    return true;
}

static void
mem_free_bo(struct vugbm_buffer *buf)
{
    g_free(buf->mmap);
}

static bool
mem_map_bo(struct vugbm_buffer *buf)
{
    return buf->mmap != NULL;
}

static void
mem_unmap_bo(struct vugbm_buffer *buf)
{
}

static void
mem_device_destroy(struct vugbm_device *dev)
{
}

#ifdef CONFIG_MEMFD
struct udmabuf_create {
        uint32_t memfd;
        uint32_t flags;
        uint64_t offset;
        uint64_t size;
};

#define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create)

static size_t
udmabuf_get_size(struct vugbm_buffer *buf)
{
    return ROUND_UP(buf->width * buf->height * 4, qemu_real_host_page_size);
}

static bool
udmabuf_alloc_bo(struct vugbm_buffer *buf)
{
    int ret;

    buf->memfd = memfd_create("udmabuf-bo", MFD_ALLOW_SEALING);
    if (buf->memfd < 0) {
        return false;
    }

    ret = ftruncate(buf->memfd, udmabuf_get_size(buf));
    if (ret < 0) {
        close(buf->memfd);
        return false;
    }

    ret = fcntl(buf->memfd, F_ADD_SEALS, F_SEAL_SHRINK);
    if (ret < 0) {
        close(buf->memfd);
        return false;
    }

    buf->stride = buf->width * 4;

    return true;
}

static void
udmabuf_free_bo(struct vugbm_buffer *buf)
{
    close(buf->memfd);
}

static bool
udmabuf_map_bo(struct vugbm_buffer *buf)
{
    buf->mmap = mmap(NULL, udmabuf_get_size(buf),
                     PROT_READ | PROT_WRITE, MAP_SHARED, buf->memfd, 0);
    if (buf->mmap == MAP_FAILED) {
        return false;
    }

    return true;
}

static bool
udmabuf_get_fd(struct vugbm_buffer *buf, int *fd)
{
    struct udmabuf_create create = {
        .memfd = buf->memfd,
        .offset = 0,
        .size = udmabuf_get_size(buf),
    };

    *fd = ioctl(buf->dev->fd, UDMABUF_CREATE, &create);

    return *fd >= 0;
}

static void
udmabuf_unmap_bo(struct vugbm_buffer *buf)
{
    munmap(buf->mmap, udmabuf_get_size(buf));
}

static void
udmabuf_device_destroy(struct vugbm_device *dev)
{
    close(dev->fd);
}
#endif

#ifdef CONFIG_GBM
static bool
alloc_bo(struct vugbm_buffer *buf)
{
    struct gbm_device *dev = buf->dev->dev;

    assert(!buf->bo);

    buf->bo = gbm_bo_create(dev, buf->width, buf->height,
                            buf->format,
                            GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR);

    if (buf->bo) {
        buf->stride = gbm_bo_get_stride(buf->bo);
        return true;
    }

    return false;
}

static void
free_bo(struct vugbm_buffer *buf)
{
    gbm_bo_destroy(buf->bo);
}

static bool
map_bo(struct vugbm_buffer *buf)
{
    uint32_t stride;

    buf->mmap = gbm_bo_map(buf->bo, 0, 0, buf->width, buf->height,
                           GBM_BO_TRANSFER_READ_WRITE, &stride,
                           &buf->mmap_data);

    assert(stride == buf->stride);

    return buf->mmap != NULL;
}

static void
unmap_bo(struct vugbm_buffer *buf)
{
    gbm_bo_unmap(buf->bo, buf->mmap_data);
}

static bool
get_fd(struct vugbm_buffer *buf, int *fd)
{
    *fd = gbm_bo_get_fd(buf->bo);

    return *fd >= 0;
}

static void
device_destroy(struct vugbm_device *dev)
{
    gbm_device_destroy(dev->dev);
}
#endif

void
vugbm_device_destroy(struct vugbm_device *dev)
{
    if (!dev->inited) {
        return;
    }

    dev->device_destroy(dev);
}

bool
vugbm_device_init(struct vugbm_device *dev, int fd)
{
    dev->fd = fd;

#ifdef CONFIG_GBM
    dev->dev = gbm_create_device(fd);
#endif

    if (0) {
        /* nothing */
    }
#ifdef CONFIG_GBM
    else if (dev->dev != NULL) {
        dev->alloc_bo = alloc_bo;
        dev->free_bo = free_bo;
        dev->get_fd = get_fd;
        dev->map_bo = map_bo;
        dev->unmap_bo = unmap_bo;
        dev->device_destroy = device_destroy;
    }
#endif
#ifdef CONFIG_MEMFD
    else if (g_file_test("/dev/udmabuf", G_FILE_TEST_EXISTS)) {
        dev->fd = open("/dev/udmabuf", O_RDWR);
        if (dev->fd < 0) {
            return false;
        }
        g_debug("Using experimental udmabuf backend");
        dev->alloc_bo = udmabuf_alloc_bo;
        dev->free_bo = udmabuf_free_bo;
        dev->get_fd = udmabuf_get_fd;
        dev->map_bo = udmabuf_map_bo;
        dev->unmap_bo = udmabuf_unmap_bo;
        dev->device_destroy = udmabuf_device_destroy;
    }
#endif
    else {
        g_debug("Using mem fallback");
        dev->alloc_bo = mem_alloc_bo;
        dev->free_bo = mem_free_bo;
        dev->map_bo = mem_map_bo;
        dev->unmap_bo = mem_unmap_bo;
        dev->device_destroy = mem_device_destroy;
        return false;
    }

    dev->inited = true;
    return true;
}

static bool
vugbm_buffer_map(struct vugbm_buffer *buf)
{
    struct vugbm_device *dev = buf->dev;

    return dev->map_bo(buf);
}

static void
vugbm_buffer_unmap(struct vugbm_buffer *buf)
{
    struct vugbm_device *dev = buf->dev;

    dev->unmap_bo(buf);
}

bool
vugbm_buffer_can_get_dmabuf_fd(struct vugbm_buffer *buffer)
{
    if (!buffer->dev->get_fd) {
        return false;
    }

    return true;
}

bool
vugbm_buffer_get_dmabuf_fd(struct vugbm_buffer *buffer, int *fd)
{
    if (!vugbm_buffer_can_get_dmabuf_fd(buffer) ||
        !buffer->dev->get_fd(buffer, fd)) {
        g_warning("Failed to get dmabuf");
        return false;
    }

    if (*fd < 0) {
        g_warning("error: dmabuf_fd < 0");
        return false;
    }

    return true;
}

bool
vugbm_buffer_create(struct vugbm_buffer *buffer, struct vugbm_device *dev,
                    uint32_t width, uint32_t height)
{
    buffer->dev = dev;
    buffer->width = width;
    buffer->height = height;
    buffer->format = GBM_FORMAT_XRGB8888;
    buffer->stride = 0; /* modified during alloc */
    if (!dev->alloc_bo(buffer)) {
        g_warning("alloc_bo failed");
        return false;
    }

    if (!vugbm_buffer_map(buffer)) {
        g_warning("map_bo failed");
        goto err;
    }

    return true;

err:
    dev->free_bo(buffer);
    return false;
}

void
vugbm_buffer_destroy(struct vugbm_buffer *buffer)
{
    struct vugbm_device *dev = buffer->dev;

    vugbm_buffer_unmap(buffer);
    dev->free_bo(buffer);
}
