/*
 * vhost-user GPU Device
 *
 * Copyright Red Hat, Inc. 2018
 *
 * Authors:
 *     Marc-André Lureau <marcandre.lureau@redhat.com>
 *
 * 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 "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-gpu.h"
#include "chardev/char-fe.h"
#include "qapi/error.h"
#include "migration/blocker.h"

typedef enum VhostUserGpuRequest {
    VHOST_USER_GPU_NONE = 0,
    VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
    VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
    VHOST_USER_GPU_GET_DISPLAY_INFO,
    VHOST_USER_GPU_CURSOR_POS,
    VHOST_USER_GPU_CURSOR_POS_HIDE,
    VHOST_USER_GPU_CURSOR_UPDATE,
    VHOST_USER_GPU_SCANOUT,
    VHOST_USER_GPU_UPDATE,
    VHOST_USER_GPU_DMABUF_SCANOUT,
    VHOST_USER_GPU_DMABUF_UPDATE,
    VHOST_USER_GPU_GET_EDID,
    VHOST_USER_GPU_DMABUF_SCANOUT2,
} VhostUserGpuRequest;

typedef struct VhostUserGpuDisplayInfoReply {
    struct virtio_gpu_resp_display_info info;
} VhostUserGpuDisplayInfoReply;

typedef struct VhostUserGpuCursorPos {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
} QEMU_PACKED VhostUserGpuCursorPos;

typedef struct VhostUserGpuCursorUpdate {
    VhostUserGpuCursorPos pos;
    uint32_t hot_x;
    uint32_t hot_y;
    uint32_t data[64 * 64];
} QEMU_PACKED VhostUserGpuCursorUpdate;

typedef struct VhostUserGpuScanout {
    uint32_t scanout_id;
    uint32_t width;
    uint32_t height;
} QEMU_PACKED VhostUserGpuScanout;

typedef struct VhostUserGpuUpdate {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
    uint32_t width;
    uint32_t height;
    uint8_t data[];
} QEMU_PACKED VhostUserGpuUpdate;

typedef struct VhostUserGpuDMABUFScanout {
    uint32_t scanout_id;
    uint32_t x;
    uint32_t y;
    uint32_t width;
    uint32_t height;
    uint32_t fd_width;
    uint32_t fd_height;
    uint32_t fd_stride;
    uint32_t fd_flags;
    int fd_drm_fourcc;
} QEMU_PACKED VhostUserGpuDMABUFScanout;

typedef struct VhostUserGpuDMABUFScanout2 {
    struct VhostUserGpuDMABUFScanout dmabuf_scanout;
    uint64_t modifier;
} QEMU_PACKED VhostUserGpuDMABUFScanout2;

typedef struct VhostUserGpuEdidRequest {
    uint32_t scanout_id;
} QEMU_PACKED VhostUserGpuEdidRequest;

typedef struct VhostUserGpuMsg {
    uint32_t request; /* VhostUserGpuRequest */
    uint32_t flags;
    uint32_t size; /* the following payload size */
    union {
        VhostUserGpuCursorPos cursor_pos;
        VhostUserGpuCursorUpdate cursor_update;
        VhostUserGpuScanout scanout;
        VhostUserGpuUpdate update;
        VhostUserGpuDMABUFScanout dmabuf_scanout;
        VhostUserGpuDMABUFScanout2 dmabuf_scanout2;
        VhostUserGpuEdidRequest edid_req;
        struct virtio_gpu_resp_edid resp_edid;
        struct virtio_gpu_resp_display_info display_info;
        uint64_t u64;
    } payload;
} QEMU_PACKED VhostUserGpuMsg;

static VhostUserGpuMsg m __attribute__ ((unused));
#define VHOST_USER_GPU_HDR_SIZE \
    (sizeof(m.request) + sizeof(m.size) + sizeof(m.flags))

#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4

#define VHOST_USER_GPU_PROTOCOL_F_EDID 0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1

static void vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked);

static void
vhost_user_gpu_handle_cursor(VhostUserGPU *g, VhostUserGpuMsg *msg)
{
    VhostUserGpuCursorPos *pos = &msg->payload.cursor_pos;
    struct virtio_gpu_scanout *s;

    if (pos->scanout_id >= g->parent_obj.conf.max_outputs) {
        return;
    }
    s = &g->parent_obj.scanout[pos->scanout_id];

    if (msg->request == VHOST_USER_GPU_CURSOR_UPDATE) {
        VhostUserGpuCursorUpdate *up = &msg->payload.cursor_update;
        if (!s->current_cursor) {
            s->current_cursor = cursor_alloc(64, 64);
        }

        s->current_cursor->hot_x = up->hot_x;
        s->current_cursor->hot_y = up->hot_y;

        memcpy(s->current_cursor->data, up->data,
               64 * 64 * sizeof(uint32_t));

        dpy_cursor_define(s->con, s->current_cursor);
    }

    dpy_mouse_set(s->con, pos->x, pos->y,
                  msg->request != VHOST_USER_GPU_CURSOR_POS_HIDE);
}

static void
vhost_user_gpu_send_msg(VhostUserGPU *g, const VhostUserGpuMsg *msg)
{
    qemu_chr_fe_write(&g->vhost_chr, (uint8_t *)msg,
                      VHOST_USER_GPU_HDR_SIZE + msg->size);
}

static void
vhost_user_gpu_unblock(VhostUserGPU *g)
{
    VhostUserGpuMsg msg = {
        .request = VHOST_USER_GPU_DMABUF_UPDATE,
        .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
    };

    vhost_user_gpu_send_msg(g, &msg);
}

static void
vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
{
    QemuConsole *con = NULL;
    struct virtio_gpu_scanout *s;

    switch (msg->request) {
    case VHOST_USER_GPU_GET_PROTOCOL_FEATURES: {
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(uint64_t),
            .payload = {
                .u64 = (1 << VHOST_USER_GPU_PROTOCOL_F_EDID) |
                       (1 << VHOST_USER_GPU_PROTOCOL_F_DMABUF2)
            }
        };

        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_SET_PROTOCOL_FEATURES: {
        break;
    }
    case VHOST_USER_GPU_GET_DISPLAY_INFO: {
        struct virtio_gpu_resp_display_info display_info = { {} };
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(struct virtio_gpu_resp_display_info),
        };

        display_info.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
        virtio_gpu_base_fill_display_info(VIRTIO_GPU_BASE(g), &display_info);
        memcpy(&reply.payload.display_info, &display_info,
               sizeof(display_info));
        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_GET_EDID: {
        VhostUserGpuEdidRequest *m = &msg->payload.edid_req;
        struct virtio_gpu_resp_edid resp = { {} };
        VhostUserGpuMsg reply = {
            .request = msg->request,
            .flags = VHOST_USER_GPU_MSG_FLAG_REPLY,
            .size = sizeof(reply.payload.resp_edid),
        };

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            error_report("invalid scanout: %d", m->scanout_id);
            break;
        }

        resp.hdr.type = VIRTIO_GPU_RESP_OK_EDID;
        virtio_gpu_base_generate_edid(VIRTIO_GPU_BASE(g), m->scanout_id, &resp);
        memcpy(&reply.payload.resp_edid, &resp, sizeof(resp));
        vhost_user_gpu_send_msg(g, &reply);
        break;
    }
    case VHOST_USER_GPU_SCANOUT: {
        VhostUserGpuScanout *m = &msg->payload.scanout;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            return;
        }

        g->parent_obj.enable = 1;
        s = &g->parent_obj.scanout[m->scanout_id];
        con = s->con;

        if (m->width == 0) {
            dpy_gfx_replace_surface(con, NULL);
        } else {
            s->ds = qemu_create_displaysurface(m->width, m->height);
            /* replace surface on next update */
        }

        break;
    }
    case VHOST_USER_GPU_DMABUF_SCANOUT2:
    case VHOST_USER_GPU_DMABUF_SCANOUT: {
        VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout;
        int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr);
        uint64_t modifier = 0;
        QemuDmaBuf *dmabuf;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            error_report("invalid scanout: %d", m->scanout_id);
            if (fd >= 0) {
                close(fd);
            }
            break;
        }

        g->parent_obj.enable = 1;
        con = g->parent_obj.scanout[m->scanout_id].con;
        dmabuf = g->dmabuf[m->scanout_id];

        if (dmabuf) {
            qemu_dmabuf_close(dmabuf);
            dpy_gl_release_dmabuf(con, dmabuf);
            g_clear_pointer(&dmabuf, qemu_dmabuf_free);
        }

        if (fd == -1) {
            dpy_gl_scanout_disable(con);
            g->dmabuf[m->scanout_id] = NULL;
            break;
        }

        if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) {
            VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2;
            modifier = m2->modifier;
        }

        dmabuf = qemu_dmabuf_new(m->width, m->height,
                                 m->fd_stride, 0, 0,
                                 m->fd_width, m->fd_height,
                                 m->fd_drm_fourcc, modifier,
                                 fd, false, m->fd_flags &
                                 VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP);

        dpy_gl_scanout_dmabuf(con, dmabuf);
        g->dmabuf[m->scanout_id] = dmabuf;
        break;
    }
    case VHOST_USER_GPU_DMABUF_UPDATE: {
        VhostUserGpuUpdate *m = &msg->payload.update;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs ||
            !g->parent_obj.scanout[m->scanout_id].con) {
            error_report("invalid scanout update: %d", m->scanout_id);
            vhost_user_gpu_unblock(g);
            break;
        }

        con = g->parent_obj.scanout[m->scanout_id].con;
        if (!console_has_gl(con)) {
            error_report("console doesn't support GL!");
            vhost_user_gpu_unblock(g);
            break;
        }
        g->backend_blocked = true;
        dpy_gl_update(con, m->x, m->y, m->width, m->height);
        break;
    }
#ifdef CONFIG_PIXMAN
    case VHOST_USER_GPU_UPDATE: {
        VhostUserGpuUpdate *m = &msg->payload.update;

        if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
            break;
        }
        s = &g->parent_obj.scanout[m->scanout_id];
        con = s->con;
        pixman_image_t *image =
            pixman_image_create_bits(PIXMAN_x8r8g8b8,
                                     m->width,
                                     m->height,
                                     (uint32_t *)m->data,
                                     m->width * 4);

        pixman_image_composite(PIXMAN_OP_SRC,
                               image, NULL, s->ds->image,
                               0, 0, 0, 0, m->x, m->y, m->width, m->height);

        pixman_image_unref(image);
        if (qemu_console_surface(con) != s->ds) {
            dpy_gfx_replace_surface(con, s->ds);
        } else {
            dpy_gfx_update(con, m->x, m->y, m->width, m->height);
        }
        break;
    }
#endif
    default:
        g_warning("unhandled message %d %d", msg->request, msg->size);
    }

    if (con && qemu_console_is_gl_blocked(con)) {
        vhost_user_gpu_update_blocked(g, true);
    }
}

static void
vhost_user_gpu_chr_read(void *opaque)
{
    VhostUserGPU *g = opaque;
    VhostUserGpuMsg *msg = NULL;
    VhostUserGpuRequest request;
    uint32_t size, flags;
    int r;

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&request, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg header: %d, %d", r, errno);
        goto end;
    }

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&flags, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg flags");
        goto end;
    }

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&size, sizeof(uint32_t));
    if (r != sizeof(uint32_t)) {
        error_report("failed to read msg size");
        goto end;
    }

    msg = g_malloc(VHOST_USER_GPU_HDR_SIZE + size);

    r = qemu_chr_fe_read_all(&g->vhost_chr,
                             (uint8_t *)&msg->payload, size);
    if (r != size) {
        error_report("failed to read msg payload %d != %d", r, size);
        goto end;
    }

    msg->request = request;
    msg->flags = flags;
    msg->size = size;

    if (request == VHOST_USER_GPU_CURSOR_UPDATE ||
        request == VHOST_USER_GPU_CURSOR_POS ||
        request == VHOST_USER_GPU_CURSOR_POS_HIDE) {
        vhost_user_gpu_handle_cursor(g, msg);
    } else {
        vhost_user_gpu_handle_display(g, msg);
    }

end:
    g_free(msg);
}

static void
vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked)
{
    qemu_set_fd_handler(g->vhost_gpu_fd,
                        blocked ? NULL : vhost_user_gpu_chr_read, NULL, g);
}

static void
vhost_user_gpu_gl_flushed(VirtIOGPUBase *b)
{
    VhostUserGPU *g = VHOST_USER_GPU(b);

    if (g->backend_blocked) {
        vhost_user_gpu_unblock(g);
        g->backend_blocked = false;
    }

    vhost_user_gpu_update_blocked(g, false);
}

static bool
vhost_user_gpu_do_set_socket(VhostUserGPU *g, Error **errp)
{
    Chardev *chr;
    int sv[2];

    if (qemu_socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
        error_setg_errno(errp, errno, "socketpair() failed");
        return false;
    }

    chr = CHARDEV(object_new(TYPE_CHARDEV_SOCKET));
    if (!chr || qemu_chr_add_client(chr, sv[0]) == -1) {
        error_setg(errp, "Failed to make socket chardev");
        goto err;
    }
    if (!qemu_chr_fe_init(&g->vhost_chr, chr, errp)) {
        goto err;
    }
    if (vhost_user_gpu_set_socket(&g->vhost->dev, sv[1]) < 0) {
        error_setg(errp, "Failed to set vhost-user-gpu socket");
        qemu_chr_fe_deinit(&g->vhost_chr, false);
        goto err;
    }

    g->vhost_gpu_fd = sv[0];
    vhost_user_gpu_update_blocked(g, false);
    close(sv[1]);
    return true;

err:
    close(sv[0]);
    close(sv[1]);
    if (chr) {
        object_unref(OBJECT(chr));
    }
    return false;
}

static void
vhost_user_gpu_get_config(VirtIODevice *vdev, uint8_t *config_data)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    VirtIOGPUBase *b = VIRTIO_GPU_BASE(vdev);
    struct virtio_gpu_config *vgconfig =
        (struct virtio_gpu_config *)config_data;
    Error *local_err = NULL;
    int ret;

    memset(config_data, 0, sizeof(struct virtio_gpu_config));

    ret = vhost_dev_get_config(&g->vhost->dev,
                               config_data, sizeof(struct virtio_gpu_config),
                               &local_err);
    if (ret) {
        error_report_err(local_err);
        return;
    }

    /* those fields are managed by qemu */
    vgconfig->num_scanouts = b->virtio_config.num_scanouts;
    vgconfig->events_read = b->virtio_config.events_read;
    vgconfig->events_clear = b->virtio_config.events_clear;
}

static void
vhost_user_gpu_set_config(VirtIODevice *vdev,
                          const uint8_t *config_data)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    VirtIOGPUBase *b = VIRTIO_GPU_BASE(vdev);
    const struct virtio_gpu_config *vgconfig =
        (const struct virtio_gpu_config *)config_data;
    int ret;

    if (vgconfig->events_clear) {
        b->virtio_config.events_read &= ~vgconfig->events_clear;
    }

    ret = vhost_dev_set_config(&g->vhost->dev, config_data,
                               0, sizeof(struct virtio_gpu_config),
                               VHOST_SET_CONFIG_TYPE_FRONTEND);
    if (ret) {
        error_report("vhost-user-gpu: set device config space failed");
        return;
    }
}

static void
vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    Error *err = NULL;

    if (val & VIRTIO_CONFIG_S_DRIVER_OK && vdev->vm_running) {
        if (!vhost_user_gpu_do_set_socket(g, &err)) {
            error_report_err(err);
            return;
        }
        vhost_user_backend_start(g->vhost);
    } else {
        /* unblock any wait and stop processing */
        if (g->vhost_gpu_fd != -1) {
            vhost_user_gpu_update_blocked(g, true);
            qemu_chr_fe_deinit(&g->vhost_chr, true);
            g->vhost_gpu_fd = -1;
        }
        vhost_user_backend_stop(g->vhost);
    }
}

static bool
vhost_user_gpu_guest_notifier_pending(VirtIODevice *vdev, int idx)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return false;
    }
    return vhost_virtqueue_pending(&g->vhost->dev, idx);
}

static void
vhost_user_gpu_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return;
    }
    vhost_virtqueue_mask(&g->vhost->dev, vdev, idx, mask);
}

static void
vhost_user_gpu_instance_init(Object *obj)
{
    VhostUserGPU *g = VHOST_USER_GPU(obj);

    g->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
    object_property_add_alias(obj, "chardev",
                              OBJECT(g->vhost), "chardev");
}

static void
vhost_user_gpu_instance_finalize(Object *obj)
{
    VhostUserGPU *g = VHOST_USER_GPU(obj);

    object_unref(OBJECT(g->vhost));
}

static void
vhost_user_gpu_reset(VirtIODevice *vdev)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);

    virtio_gpu_base_reset(VIRTIO_GPU_BASE(vdev));

    vhost_user_backend_stop(g->vhost);
}

static int
vhost_user_gpu_config_change(struct vhost_dev *dev)
{
    error_report("vhost-user-gpu: unhandled backend config change");
    return -1;
}

static const VhostDevConfigOps config_ops = {
    .vhost_dev_config_notifier = vhost_user_gpu_config_change,
};

static void
vhost_user_gpu_device_realize(DeviceState *qdev, Error **errp)
{
    VhostUserGPU *g = VHOST_USER_GPU(qdev);
    VirtIODevice *vdev = VIRTIO_DEVICE(g);

    vhost_dev_set_config_notifier(&g->vhost->dev, &config_ops);
    if (vhost_user_backend_dev_init(g->vhost, vdev, 2, errp) < 0) {
        return;
    }

    /* existing backend may send DMABUF, so let's add that requirement */
    g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED;
    if (virtio_has_feature(g->vhost->dev.features, VIRTIO_GPU_F_VIRGL)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED;
    }
    if (virtio_has_feature(g->vhost->dev.features, VIRTIO_GPU_F_EDID)) {
        g->parent_obj.conf.flags |= 1 << VIRTIO_GPU_FLAG_EDID_ENABLED;
    } else {
        error_report("EDID requested but the backend doesn't support it.");
        g->parent_obj.conf.flags &= ~(1 << VIRTIO_GPU_FLAG_EDID_ENABLED);
    }

    if (!virtio_gpu_base_device_realize(qdev, NULL, NULL, errp)) {
        return;
    }

    g->vhost_gpu_fd = -1;
}

static struct vhost_dev *vhost_user_gpu_get_vhost(VirtIODevice *vdev)
{
    VhostUserGPU *g = VHOST_USER_GPU(vdev);
    return g->vhost ? &g->vhost->dev : NULL;
}

static Property vhost_user_gpu_properties[] = {
    VIRTIO_GPU_BASE_PROPERTIES(VhostUserGPU, parent_obj.conf),
    DEFINE_PROP_END_OF_LIST(),
};

static void
vhost_user_gpu_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
    VirtIOGPUBaseClass *vgc = VIRTIO_GPU_BASE_CLASS(klass);

    vgc->gl_flushed = vhost_user_gpu_gl_flushed;

    vdc->realize = vhost_user_gpu_device_realize;
    vdc->reset = vhost_user_gpu_reset;
    vdc->set_status   = vhost_user_gpu_set_status;
    vdc->guest_notifier_mask = vhost_user_gpu_guest_notifier_mask;
    vdc->guest_notifier_pending = vhost_user_gpu_guest_notifier_pending;
    vdc->get_config = vhost_user_gpu_get_config;
    vdc->set_config = vhost_user_gpu_set_config;
    vdc->get_vhost = vhost_user_gpu_get_vhost;

    device_class_set_props(dc, vhost_user_gpu_properties);
}

static const TypeInfo vhost_user_gpu_info = {
    .name = TYPE_VHOST_USER_GPU,
    .parent = TYPE_VIRTIO_GPU_BASE,
    .instance_size = sizeof(VhostUserGPU),
    .instance_init = vhost_user_gpu_instance_init,
    .instance_finalize = vhost_user_gpu_instance_finalize,
    .class_init = vhost_user_gpu_class_init,
};
module_obj(TYPE_VHOST_USER_GPU);
module_kconfig(VHOST_USER_GPU);

static void vhost_user_gpu_register_types(void)
{
    type_register_static(&vhost_user_gpu_info);
}

type_init(vhost_user_gpu_register_types)
