diff options
-rw-r--r-- | hw/display/vhost-user-gpu.c | 32 | ||||
-rw-r--r-- | hw/display/virtio-gpu-udmabuf.c | 27 | ||||
-rw-r--r-- | hw/vfio/display.c | 32 | ||||
-rw-r--r-- | include/hw/vfio/vfio-common.h | 2 | ||||
-rw-r--r-- | include/hw/virtio/virtio-gpu.h | 4 | ||||
-rw-r--r-- | include/ui/console.h | 20 | ||||
-rw-r--r-- | include/ui/dmabuf.h | 49 | ||||
-rw-r--r-- | qemu-options.hx | 4 | ||||
-rw-r--r-- | ui/console.c | 4 | ||||
-rw-r--r-- | ui/dbus-console.c | 9 | ||||
-rw-r--r-- | ui/dbus-listener.c | 71 | ||||
-rw-r--r-- | ui/dmabuf.c | 229 | ||||
-rw-r--r-- | ui/egl-headless.c | 23 | ||||
-rw-r--r-- | ui/egl-helpers.c | 59 | ||||
-rw-r--r-- | ui/gtk-egl.c | 53 | ||||
-rw-r--r-- | ui/gtk-gl-area.c | 42 | ||||
-rw-r--r-- | ui/gtk.c | 32 | ||||
-rw-r--r-- | ui/meson.build | 1 | ||||
-rw-r--r-- | ui/sdl2.c | 1 | ||||
-rw-r--r-- | ui/spice-display.c | 50 | ||||
-rw-r--r-- | ui/trace-events | 1 | ||||
-rw-r--r-- | ui/vnc.c | 5 |
22 files changed, 547 insertions, 203 deletions
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 709c8a02a1..e4b398d26c 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -249,6 +249,7 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) 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) { @@ -261,30 +262,33 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) g->parent_obj.enable = 1; con = g->parent_obj.scanout[m->scanout_id].con; - dmabuf = &g->dmabuf[m->scanout_id]; - if (dmabuf->fd >= 0) { - close(dmabuf->fd); - dmabuf->fd = -1; + 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); } - dpy_gl_release_dmabuf(con, dmabuf); + if (fd == -1) { dpy_gl_scanout_disable(con); + g->dmabuf[m->scanout_id] = NULL; break; } - *dmabuf = (QemuDmaBuf) { - .fd = fd, - .width = m->fd_width, - .height = m->fd_height, - .stride = m->fd_stride, - .fourcc = m->fd_drm_fourcc, - .y0_top = m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP, - }; + if (msg->request == VHOST_USER_GPU_DMABUF_SCANOUT2) { VhostUserGpuDMABUFScanout2 *m2 = &msg->payload.dmabuf_scanout2; - dmabuf->modifier = m2->modifier; + modifier = m2->modifier; } + dmabuf = qemu_dmabuf_new(m->fd_width, m->fd_height, + m->fd_stride, 0, 0, 0, 0, + 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: { diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index d51184d658..c02ec6d37d 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -162,7 +162,8 @@ static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf) struct virtio_gpu_scanout *scanout; scanout = &g->parent_obj.scanout[dmabuf->scanout_id]; - dpy_gl_release_dmabuf(scanout->con, &dmabuf->buf); + dpy_gl_release_dmabuf(scanout->con, dmabuf->buf); + g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); QTAILQ_REMOVE(&g->dmabuf.bufs, dmabuf, next); g_free(dmabuf); } @@ -181,17 +182,10 @@ static VGPUDMABuf } dmabuf = g_new0(VGPUDMABuf, 1); - dmabuf->buf.width = r->width; - dmabuf->buf.height = r->height; - dmabuf->buf.stride = fb->stride; - dmabuf->buf.x = r->x; - dmabuf->buf.y = r->y; - dmabuf->buf.backing_width = fb->width; - dmabuf->buf.backing_height = fb->height; - dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format); - dmabuf->buf.fd = res->dmabuf_fd; - dmabuf->buf.allow_fences = true; - dmabuf->buf.draw_submitted = false; + dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride, + r->x, r->y, fb->width, fb->height, + qemu_pixman_to_drm_format(fb->format), + 0, res->dmabuf_fd, true, false); dmabuf->scanout_id = scanout_id; QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next); @@ -206,6 +200,7 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, { struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id]; VGPUDMABuf *new_primary, *old_primary = NULL; + uint32_t width, height; new_primary = virtio_gpu_create_dmabuf(g, scanout_id, res, fb, r); if (!new_primary) { @@ -216,11 +211,11 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, old_primary = g->dmabuf.primary[scanout_id]; } + width = qemu_dmabuf_get_width(new_primary->buf); + height = qemu_dmabuf_get_height(new_primary->buf); g->dmabuf.primary[scanout_id] = new_primary; - qemu_console_resize(scanout->con, - new_primary->buf.width, - new_primary->buf.height); - dpy_gl_scanout_dmabuf(scanout->con, &new_primary->buf); + qemu_console_resize(scanout->con, width, height); + dpy_gl_scanout_dmabuf(scanout->con, new_primary->buf); if (old_primary) { virtio_gpu_free_dmabuf(g, old_primary); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 1aa440c663..fe624a6c9b 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -241,14 +241,11 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, dmabuf = g_new0(VFIODMABuf, 1); dmabuf->dmabuf_id = plane.dmabuf_id; - dmabuf->buf.width = plane.width; - dmabuf->buf.height = plane.height; - dmabuf->buf.backing_width = plane.width; - dmabuf->buf.backing_height = plane.height; - dmabuf->buf.stride = plane.stride; - dmabuf->buf.fourcc = plane.drm_format; - dmabuf->buf.modifier = plane.drm_format_mod; - dmabuf->buf.fd = fd; + dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height, + plane.stride, 0, 0, plane.width, + plane.height, plane.drm_format, + plane.drm_format_mod, fd, false, false); + if (plane_type == DRM_PLANE_TYPE_CURSOR) { vfio_display_update_cursor(dmabuf, &plane); } @@ -260,8 +257,10 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, static void vfio_display_free_one_dmabuf(VFIODisplay *dpy, VFIODMABuf *dmabuf) { QTAILQ_REMOVE(&dpy->dmabuf.bufs, dmabuf, next); - dpy_gl_release_dmabuf(dpy->con, &dmabuf->buf); - close(dmabuf->buf.fd); + + qemu_dmabuf_close(dmabuf->buf); + dpy_gl_release_dmabuf(dpy->con, dmabuf->buf); + g_clear_pointer(&dmabuf->buf, qemu_dmabuf_free); g_free(dmabuf); } @@ -286,6 +285,7 @@ static void vfio_display_dmabuf_update(void *opaque) VFIOPCIDevice *vdev = opaque; VFIODisplay *dpy = vdev->dpy; VFIODMABuf *primary, *cursor; + uint32_t width, height; bool free_bufs = false, new_cursor = false; primary = vfio_display_get_dmabuf(vdev, DRM_PLANE_TYPE_PRIMARY); @@ -296,11 +296,13 @@ static void vfio_display_dmabuf_update(void *opaque) return; } + width = qemu_dmabuf_get_width(primary->buf); + height = qemu_dmabuf_get_height(primary->buf); + if (dpy->dmabuf.primary != primary) { dpy->dmabuf.primary = primary; - qemu_console_resize(dpy->con, - primary->buf.width, primary->buf.height); - dpy_gl_scanout_dmabuf(dpy->con, &primary->buf); + qemu_console_resize(dpy->con, width, height); + dpy_gl_scanout_dmabuf(dpy->con, primary->buf); free_bufs = true; } @@ -314,7 +316,7 @@ static void vfio_display_dmabuf_update(void *opaque) if (cursor && (new_cursor || cursor->hot_updates)) { bool have_hot = (cursor->hot_x != 0xffffffff && cursor->hot_y != 0xffffffff); - dpy_gl_cursor_dmabuf(dpy->con, &cursor->buf, have_hot, + dpy_gl_cursor_dmabuf(dpy->con, cursor->buf, have_hot, cursor->hot_x, cursor->hot_y); cursor->hot_updates = 0; } else if (!cursor && new_cursor) { @@ -328,7 +330,7 @@ static void vfio_display_dmabuf_update(void *opaque) cursor->pos_updates = 0; } - dpy_gl_update(dpy->con, 0, 0, primary->buf.width, primary->buf.height); + dpy_gl_update(dpy->con, 0, 0, width, height); if (free_bufs) { vfio_display_free_dmabufs(vdev); diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h index b9da6c08ef..d66e27db02 100644 --- a/include/hw/vfio/vfio-common.h +++ b/include/hw/vfio/vfio-common.h @@ -148,7 +148,7 @@ typedef struct VFIOGroup { } VFIOGroup; typedef struct VFIODMABuf { - QemuDmaBuf buf; + QemuDmaBuf *buf; uint32_t pos_x, pos_y, pos_updates; uint32_t hot_x, hot_y, hot_updates; int dmabuf_id; diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index ed44cdad6b..56d6e821bf 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -169,7 +169,7 @@ struct VirtIOGPUBaseClass { DEFINE_PROP_UINT32("yres", _state, _conf.yres, 800) typedef struct VGPUDMABuf { - QemuDmaBuf buf; + QemuDmaBuf *buf; uint32_t scanout_id; QTAILQ_ENTRY(VGPUDMABuf) next; } VGPUDMABuf; @@ -238,7 +238,7 @@ struct VhostUserGPU { VhostUserBackend *vhost; int vhost_gpu_fd; /* closed by the chardev */ CharBackend vhost_chr; - QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; + QemuDmaBuf *dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; bool backend_blocked; }; diff --git a/include/ui/console.h b/include/ui/console.h index 0bc7a00ac0..a208a68b88 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -7,6 +7,7 @@ #include "qapi/qapi-types-ui.h" #include "ui/input.h" #include "ui/surface.h" +#include "ui/dmabuf.h" #define TYPE_QEMU_CONSOLE "qemu-console" OBJECT_DECLARE_TYPE(QemuConsole, QemuConsoleClass, QEMU_CONSOLE) @@ -185,25 +186,6 @@ struct QEMUGLParams { int minor_ver; }; -typedef struct QemuDmaBuf { - int fd; - uint32_t width; - uint32_t height; - uint32_t stride; - uint32_t fourcc; - uint64_t modifier; - uint32_t texture; - uint32_t x; - uint32_t y; - uint32_t backing_width; - uint32_t backing_height; - bool y0_top; - void *sync; - int fence_fd; - bool allow_fences; - bool draw_submitted; -} QemuDmaBuf; - enum display_scanout { SCANOUT_NONE, SCANOUT_SURFACE, diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h new file mode 100644 index 0000000000..dc74ba895a --- /dev/null +++ b/include/ui/dmabuf.h @@ -0,0 +1,49 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * QemuDmaBuf struct and helpers used for accessing its data + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef DMABUF_H +#define DMABUF_H + +typedef struct QemuDmaBuf QemuDmaBuf; + +QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, + uint32_t stride, uint32_t x, + uint32_t y, uint32_t backing_width, + uint32_t backing_height, uint32_t fourcc, + uint64_t modifier, int dmabuf_fd, + bool allow_fences, bool y0_top); +void qemu_dmabuf_free(QemuDmaBuf *dmabuf); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free); + +int qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf); +int qemu_dmabuf_dup_fd(QemuDmaBuf *dmabuf); +void qemu_dmabuf_close(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_height(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_stride(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_fourcc(QemuDmaBuf *dmabuf); +uint64_t qemu_dmabuf_get_modifier(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_texture(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_x(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_y(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_backing_width(QemuDmaBuf *dmabuf); +uint32_t qemu_dmabuf_get_backing_height(QemuDmaBuf *dmabuf); +bool qemu_dmabuf_get_y0_top(QemuDmaBuf *dmabuf); +void *qemu_dmabuf_get_sync(QemuDmaBuf *dmabuf); +int32_t qemu_dmabuf_get_fence_fd(QemuDmaBuf *dmabuf); +bool qemu_dmabuf_get_allow_fences(QemuDmaBuf *dmabuf); +bool qemu_dmabuf_get_draw_submitted(QemuDmaBuf *dmabuf); +void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture); +void qemu_dmabuf_set_fence_fd(QemuDmaBuf *dmabuf, int32_t fence_fd); +void qemu_dmabuf_set_sync(QemuDmaBuf *dmabuf, void *sync); +void qemu_dmabuf_set_draw_submitted(QemuDmaBuf *dmabuf, bool draw_submitted); +void qemu_dmabuf_set_fd(QemuDmaBuf *dmabuf, int32_t fd); + +#endif diff --git a/qemu-options.hx b/qemu-options.hx index f5c01eeeb4..4d19660336 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2516,6 +2516,10 @@ SRST host. It is possible to control the websocket listen address independently, using the syntax ``websocket``\ =host:port. + Websocket could be allowed over UNIX domain socket, using the syntax + ``websocket``\ =unix:path, where path is the location of a unix socket + to listen for connections on. + If no TLS credentials are provided, the websocket connection runs in unencrypted mode. If TLS credentials are provided, the websocket connection requires encrypted client connections. diff --git a/ui/console.c b/ui/console.c index 43226c5c14..1b2cd0c736 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1459,7 +1459,7 @@ int qemu_console_get_width(QemuConsole *con, int fallback) } switch (con->scanout.kind) { case SCANOUT_DMABUF: - return con->scanout.dmabuf->width; + return qemu_dmabuf_get_width(con->scanout.dmabuf); case SCANOUT_TEXTURE: return con->scanout.texture.width; case SCANOUT_SURFACE: @@ -1476,7 +1476,7 @@ int qemu_console_get_height(QemuConsole *con, int fallback) } switch (con->scanout.kind) { case SCANOUT_DMABUF: - return con->scanout.dmabuf->height; + return qemu_dmabuf_get_height(con->scanout.dmabuf); case SCANOUT_TEXTURE: return con->scanout.texture.height; case SCANOUT_SURFACE: diff --git a/ui/dbus-console.c b/ui/dbus-console.c index 49da9ccc83..578b67f62b 100644 --- a/ui/dbus-console.c +++ b/ui/dbus-console.c @@ -110,11 +110,14 @@ static void dbus_gl_scanout_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf) { + uint32_t width, height; + DBusDisplayConsole *ddc = container_of(dcl, DBusDisplayConsole, dcl); - dbus_display_console_set_size(ddc, - dmabuf->width, - dmabuf->height); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + + dbus_display_console_set_size(ddc, width, height); } static void diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 4a0a5d78f9..5490088043 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -278,29 +278,33 @@ static void dbus_scanout_dmabuf(DisplayChangeListener *dcl, DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); g_autoptr(GError) err = NULL; g_autoptr(GUnixFDList) fd_list = NULL; + int fd; + uint32_t width, height, stride, fourcc; + uint64_t modifier; + bool y0_top; + fd = qemu_dmabuf_get_fd(dmabuf); fd_list = g_unix_fd_list_new(); - if (g_unix_fd_list_append(fd_list, dmabuf->fd, &err) != 0) { + if (g_unix_fd_list_append(fd_list, fd, &err) != 0) { error_report("Failed to setup dmabuf fdlist: %s", err->message); return; } ddl_discard_pending_messages(ddl); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + stride = qemu_dmabuf_get_stride(dmabuf); + fourcc = qemu_dmabuf_get_fourcc(dmabuf); + modifier = qemu_dmabuf_get_modifier(dmabuf); + y0_top = qemu_dmabuf_get_y0_top(dmabuf); + /* FIXME: add missing x/y/w/h support */ qemu_dbus_display1_listener_call_scanout_dmabuf( - ddl->proxy, - g_variant_new_handle(0), - dmabuf->width, - dmabuf->height, - dmabuf->stride, - dmabuf->fourcc, - dmabuf->modifier, - dmabuf->y0_top, - G_DBUS_CALL_FLAGS_NONE, - -1, - fd_list, - NULL, NULL, NULL); + ddl->proxy, g_variant_new_handle(0), + width, height, stride, fourcc, modifier, + y0_top, G_DBUS_CALL_FLAGS_NONE, + -1, fd_list, NULL, NULL, NULL); } #endif /* GBM */ #endif /* OPENGL */ @@ -438,28 +442,24 @@ static void dbus_scanout_texture(DisplayChangeListener *dcl, trace_dbus_scanout_texture(tex_id, backing_y_0_top, backing_width, backing_height, x, y, w, h); #ifdef CONFIG_GBM - QemuDmaBuf dmabuf = { - .width = w, - .height = h, - .y0_top = backing_y_0_top, - .x = x, - .y = y, - .backing_width = backing_width, - .backing_height = backing_height, - }; + g_autoptr(QemuDmaBuf) dmabuf = NULL; + int fd; + uint32_t stride, fourcc; + uint64_t modifier; assert(tex_id); - dmabuf.fd = egl_get_fd_for_texture( - tex_id, (EGLint *)&dmabuf.stride, - (EGLint *)&dmabuf.fourcc, - &dmabuf.modifier); - if (dmabuf.fd < 0) { + fd = egl_get_fd_for_texture(tex_id, (EGLint *)&stride, (EGLint *)&fourcc, + &modifier); + if (fd < 0) { error_report("%s: failed to get fd for texture", __func__); return; } + dmabuf = qemu_dmabuf_new(w, h, stride, x, y, backing_width, + backing_height, fourcc, modifier, fd, + false, backing_y_0_top); - dbus_scanout_dmabuf(dcl, &dmabuf); - close(dmabuf.fd); + dbus_scanout_dmabuf(dcl, dmabuf); + qemu_dmabuf_close(dmabuf); #endif #ifdef WIN32 @@ -488,6 +488,7 @@ static void dbus_cursor_dmabuf(DisplayChangeListener *dcl, DisplaySurface *ds; GVariant *v_data = NULL; egl_fb cursor_fb = EGL_FB_INIT; + uint32_t width, height, texture; if (!dmabuf) { qemu_dbus_display1_listener_call_mouse_set( @@ -497,12 +498,16 @@ static void dbus_cursor_dmabuf(DisplayChangeListener *dcl, } egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - egl_fb_setup_for_tex(&cursor_fb, dmabuf->width, dmabuf->height, - dmabuf->texture, false); - ds = qemu_create_displaysurface(dmabuf->width, dmabuf->height); + + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + + egl_fb_setup_for_tex(&cursor_fb, width, height, texture, false); + ds = qemu_create_displaysurface(width, height); egl_fb_read(ds, &cursor_fb); v_data = g_variant_new_from_data( diff --git a/ui/dmabuf.c b/ui/dmabuf.c new file mode 100644 index 0000000000..df7a09703f --- /dev/null +++ b/ui/dmabuf.c @@ -0,0 +1,229 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * QemuDmaBuf struct and helpers used for accessing its data + * + * 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 "ui/dmabuf.h" + +struct QemuDmaBuf { + int fd; + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t fourcc; + uint64_t modifier; + uint32_t texture; + uint32_t x; + uint32_t y; + uint32_t backing_width; + uint32_t backing_height; + bool y0_top; + void *sync; + int fence_fd; + bool allow_fences; + bool draw_submitted; +}; + +QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height, + uint32_t stride, uint32_t x, + uint32_t y, uint32_t backing_width, + uint32_t backing_height, uint32_t fourcc, + uint64_t modifier, int32_t dmabuf_fd, + bool allow_fences, bool y0_top) { + QemuDmaBuf *dmabuf; + + dmabuf = g_new0(QemuDmaBuf, 1); + + dmabuf->width = width; + dmabuf->height = height; + dmabuf->stride = stride; + dmabuf->x = x; + dmabuf->y = y; + dmabuf->backing_width = backing_width; + dmabuf->backing_height = backing_height; + dmabuf->fourcc = fourcc; + dmabuf->modifier = modifier; + dmabuf->fd = dmabuf_fd; + dmabuf->allow_fences = allow_fences; + dmabuf->y0_top = y0_top; + dmabuf->fence_fd = -1; + + return dmabuf; +} + +void qemu_dmabuf_free(QemuDmaBuf *dmabuf) +{ + if (dmabuf == NULL) { + return; + } + + g_free(dmabuf); +} + +int qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->fd; +} + +int qemu_dmabuf_dup_fd(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + if (dmabuf->fd >= 0) { + return dup(dmabuf->fd); + } else { + return -1; + } +} + +void qemu_dmabuf_close(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + if (dmabuf->fd >= 0) { + close(dmabuf->fd); + dmabuf->fd = -1; + } +} + +uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->width; +} + +uint32_t qemu_dmabuf_get_height(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->height; +} + +uint32_t qemu_dmabuf_get_stride(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->stride; +} + +uint32_t qemu_dmabuf_get_fourcc(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->fourcc; +} + +uint64_t qemu_dmabuf_get_modifier(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->modifier; +} + +uint32_t qemu_dmabuf_get_texture(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->texture; +} + +uint32_t qemu_dmabuf_get_x(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->x; +} + +uint32_t qemu_dmabuf_get_y(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->y; +} + +uint32_t qemu_dmabuf_get_backing_width(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->backing_width; +} + +uint32_t qemu_dmabuf_get_backing_height(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->backing_height; +} + +bool qemu_dmabuf_get_y0_top(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->y0_top; +} + +void *qemu_dmabuf_get_sync(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->sync; +} + +int32_t qemu_dmabuf_get_fence_fd(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->fence_fd; +} + +bool qemu_dmabuf_get_allow_fences(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->allow_fences; +} + +bool qemu_dmabuf_get_draw_submitted(QemuDmaBuf *dmabuf) +{ + assert(dmabuf != NULL); + + return dmabuf->draw_submitted; +} + +void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture) +{ + assert(dmabuf != NULL); + dmabuf->texture = texture; +} + +void qemu_dmabuf_set_fence_fd(QemuDmaBuf *dmabuf, int32_t fence_fd) +{ + assert(dmabuf != NULL); + dmabuf->fence_fd = fence_fd; +} + +void qemu_dmabuf_set_sync(QemuDmaBuf *dmabuf, void *sync) +{ + assert(dmabuf != NULL); + dmabuf->sync = sync; +} + +void qemu_dmabuf_set_draw_submitted(QemuDmaBuf *dmabuf, bool draw_submitted) +{ + assert(dmabuf != NULL); + dmabuf->draw_submitted = draw_submitted; +} + +void qemu_dmabuf_set_fd(QemuDmaBuf *dmabuf, int32_t fd) +{ + assert(dmabuf != NULL); + dmabuf->fd = fd; +} diff --git a/ui/egl-headless.c b/ui/egl-headless.c index d5637dadb2..6187249c73 100644 --- a/ui/egl-headless.c +++ b/ui/egl-headless.c @@ -85,29 +85,38 @@ static void egl_scanout_texture(DisplayChangeListener *dcl, static void egl_scanout_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf) { + uint32_t width, height, texture; + egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - egl_scanout_texture(dcl, dmabuf->texture, - false, dmabuf->width, dmabuf->height, - 0, 0, dmabuf->width, dmabuf->height, NULL); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + + egl_scanout_texture(dcl, texture, false, width, height, 0, 0, + width, height, NULL); } static void egl_cursor_dmabuf(DisplayChangeListener *dcl, QemuDmaBuf *dmabuf, bool have_hot, uint32_t hot_x, uint32_t hot_y) { + uint32_t width, height, texture; egl_dpy *edpy = container_of(dcl, egl_dpy, dcl); if (dmabuf) { egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - egl_fb_setup_for_tex(&edpy->cursor_fb, dmabuf->width, dmabuf->height, - dmabuf->texture, false); + + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + egl_fb_setup_for_tex(&edpy->cursor_fb, width, height, texture, false); } else { egl_fb_destroy(&edpy->cursor_fb); } diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c index 3d19dbe382..99b2ebbe23 100644 --- a/ui/egl-helpers.c +++ b/ui/egl-helpers.c @@ -146,10 +146,10 @@ void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip) glViewport(0, 0, dst->width, dst->height); if (src->dmabuf) { - x1 = src->dmabuf->x; - y1 = src->dmabuf->y; - w = src->dmabuf->width; - h = src->dmabuf->height; + x1 = qemu_dmabuf_get_x(src->dmabuf); + y1 = qemu_dmabuf_get_y(src->dmabuf); + w = qemu_dmabuf_get_width(src->dmabuf); + h = qemu_dmabuf_get_height(src->dmabuf); } w = (x1 + w) > src->width ? src->width - x1 : w; @@ -308,30 +308,33 @@ void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf) EGLImageKHR image = EGL_NO_IMAGE_KHR; EGLint attrs[64]; int i = 0; + uint64_t modifier; + uint32_t texture = qemu_dmabuf_get_texture(dmabuf); - if (dmabuf->texture != 0) { + if (texture != 0) { return; } attrs[i++] = EGL_WIDTH; - attrs[i++] = dmabuf->backing_width; + attrs[i++] = qemu_dmabuf_get_backing_width(dmabuf); attrs[i++] = EGL_HEIGHT; - attrs[i++] = dmabuf->backing_height; + attrs[i++] = qemu_dmabuf_get_backing_height(dmabuf); attrs[i++] = EGL_LINUX_DRM_FOURCC_EXT; - attrs[i++] = dmabuf->fourcc; + attrs[i++] = qemu_dmabuf_get_fourcc(dmabuf); attrs[i++] = EGL_DMA_BUF_PLANE0_FD_EXT; - attrs[i++] = dmabuf->fd; + attrs[i++] = qemu_dmabuf_get_fd(dmabuf); attrs[i++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; - attrs[i++] = dmabuf->stride; + attrs[i++] = qemu_dmabuf_get_stride(dmabuf); attrs[i++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attrs[i++] = 0; #ifdef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT - if (dmabuf->modifier) { + modifier = qemu_dmabuf_get_modifier(dmabuf); + if (modifier) { attrs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; - attrs[i++] = (dmabuf->modifier >> 0) & 0xffffffff; + attrs[i++] = (modifier >> 0) & 0xffffffff; attrs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; - attrs[i++] = (dmabuf->modifier >> 32) & 0xffffffff; + attrs[i++] = (modifier >> 32) & 0xffffffff; } #endif attrs[i++] = EGL_NONE; @@ -345,8 +348,9 @@ void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf) return; } - glGenTextures(1, &dmabuf->texture); - glBindTexture(GL_TEXTURE_2D, dmabuf->texture); + glGenTextures(1, &texture); + qemu_dmabuf_set_texture(dmabuf, texture); + glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -356,12 +360,15 @@ void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf) void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf) { - if (dmabuf->texture == 0) { + uint32_t texture; + + texture = qemu_dmabuf_get_texture(dmabuf); + if (texture == 0) { return; } - glDeleteTextures(1, &dmabuf->texture); - dmabuf->texture = 0; + glDeleteTextures(1, &texture); + qemu_dmabuf_set_texture(dmabuf, 0); } void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf) @@ -375,18 +382,22 @@ void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf) sync = eglCreateSyncKHR(qemu_egl_display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); if (sync != EGL_NO_SYNC_KHR) { - dmabuf->sync = sync; + qemu_dmabuf_set_sync(dmabuf, sync); } } } void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf) { - if (dmabuf->sync) { - dmabuf->fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display, - dmabuf->sync); - eglDestroySyncKHR(qemu_egl_display, dmabuf->sync); - dmabuf->sync = NULL; + void *sync = qemu_dmabuf_get_sync(dmabuf); + int fence_fd; + + if (sync) { + fence_fd = eglDupNativeFenceFDANDROID(qemu_egl_display, + sync); + qemu_dmabuf_set_fence_fd(dmabuf, fence_fd); + eglDestroySyncKHR(qemu_egl_display, sync); + qemu_dmabuf_set_sync(dmabuf, NULL); } } diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c index 3af5ac5bcf..0473f689c9 100644 --- a/ui/gtk-egl.c +++ b/ui/gtk-egl.c @@ -70,6 +70,7 @@ void gd_egl_draw(VirtualConsole *vc) QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; #endif int ww, wh, ws; + int fence_fd; if (!vc->gfx.gls) { return; @@ -83,10 +84,10 @@ void gd_egl_draw(VirtualConsole *vc) if (vc->gfx.scanout_mode) { #ifdef CONFIG_GBM if (dmabuf) { - if (!dmabuf->draw_submitted) { + if (!qemu_dmabuf_get_draw_submitted(dmabuf)) { return; } else { - dmabuf->draw_submitted = false; + qemu_dmabuf_set_draw_submitted(dmabuf, false); } } #endif @@ -99,8 +100,9 @@ void gd_egl_draw(VirtualConsole *vc) #ifdef CONFIG_GBM if (dmabuf) { egl_dmabuf_create_fence(dmabuf); - if (dmabuf->fence_fd > 0) { - qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc); + fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); return; } graphic_hw_gl_block(vc->gfx.dcl.con, false); @@ -149,7 +151,9 @@ void gd_egl_refresh(DisplayChangeListener *dcl) gd_update_monitor_refresh_rate( vc, vc->window ? vc->window : vc->gfx.drawing_area); - if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) { + if (vc->gfx.guest_fb.dmabuf && + qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { + gd_egl_draw(vc); return; } @@ -264,22 +268,30 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl, { #ifdef CONFIG_GBM VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + uint32_t x, y, width, height, backing_width, backing_height, texture; + bool y0_top; eglMakeCurrent(qemu_egl_display, vc->gfx.esurface, vc->gfx.esurface, vc->gfx.ectx); egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - gd_egl_scanout_texture(dcl, dmabuf->texture, - dmabuf->y0_top, - dmabuf->backing_width, dmabuf->backing_height, - dmabuf->x, dmabuf->y, dmabuf->width, - dmabuf->height, NULL); + x = qemu_dmabuf_get_x(dmabuf); + y = qemu_dmabuf_get_y(dmabuf); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + backing_width = qemu_dmabuf_get_backing_width(dmabuf); + backing_height = qemu_dmabuf_get_backing_height(dmabuf); + y0_top = qemu_dmabuf_get_y0_top(dmabuf); + + gd_egl_scanout_texture(dcl, texture, y0_top, backing_width, backing_height, + x, y, width, height, NULL); - if (dmabuf->allow_fences) { + if (qemu_dmabuf_get_allow_fences(dmabuf)) { vc->gfx.guest_fb.dmabuf = dmabuf; } #endif @@ -291,15 +303,19 @@ void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl, { #ifdef CONFIG_GBM VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + uint32_t backing_width, backing_height, texture; if (dmabuf) { egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - egl_fb_setup_for_tex(&vc->gfx.cursor_fb, - dmabuf->backing_width, dmabuf->backing_height, - dmabuf->texture, false); + + backing_width = qemu_dmabuf_get_backing_width(dmabuf); + backing_height = qemu_dmabuf_get_backing_height(dmabuf); + egl_fb_setup_for_tex(&vc->gfx.cursor_fb, backing_width, backing_height, + texture, false); } else { egl_fb_destroy(&vc->gfx.cursor_fb); } @@ -363,9 +379,10 @@ void gd_egl_flush(DisplayChangeListener *dcl, VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); GtkWidget *area = vc->gfx.drawing_area; - if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) { + if (vc->gfx.guest_fb.dmabuf && + !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { graphic_hw_gl_block(vc->gfx.dcl.con, true); - vc->gfx.guest_fb.dmabuf->draw_submitted = true; + qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); gtk_egl_set_scanout_mode(vc, true); gtk_widget_queue_draw_area(area, x, y, w, h); return; diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c index 52dcac161e..b628b35451 100644 --- a/ui/gtk-gl-area.c +++ b/ui/gtk-gl-area.c @@ -60,10 +60,10 @@ void gd_gl_area_draw(VirtualConsole *vc) #ifdef CONFIG_GBM if (dmabuf) { - if (!dmabuf->draw_submitted) { + if (!qemu_dmabuf_get_draw_submitted(dmabuf)) { return; } else { - dmabuf->draw_submitted = false; + qemu_dmabuf_set_draw_submitted(dmabuf, false); } } #endif @@ -85,9 +85,11 @@ void gd_gl_area_draw(VirtualConsole *vc) glFlush(); #ifdef CONFIG_GBM if (dmabuf) { + int fence_fd; egl_dmabuf_create_fence(dmabuf); - if (dmabuf->fence_fd > 0) { - qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc); + fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, gd_hw_gl_flushed, NULL, vc); return; } graphic_hw_gl_block(vc->gfx.dcl.con, false); @@ -125,7 +127,9 @@ void gd_gl_area_refresh(DisplayChangeListener *dcl) gd_update_monitor_refresh_rate(vc, vc->window ? vc->window : vc->gfx.drawing_area); - if (vc->gfx.guest_fb.dmabuf && vc->gfx.guest_fb.dmabuf->draw_submitted) { + if (vc->gfx.guest_fb.dmabuf && + qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { + gd_gl_area_draw(vc); return; } @@ -285,9 +289,10 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl, { VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); - if (vc->gfx.guest_fb.dmabuf && !vc->gfx.guest_fb.dmabuf->draw_submitted) { + if (vc->gfx.guest_fb.dmabuf && + !qemu_dmabuf_get_draw_submitted(vc->gfx.guest_fb.dmabuf)) { graphic_hw_gl_block(vc->gfx.dcl.con, true); - vc->gfx.guest_fb.dmabuf->draw_submitted = true; + qemu_dmabuf_set_draw_submitted(vc->gfx.guest_fb.dmabuf, true); gtk_gl_area_set_scanout_mode(vc, true); } gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area)); @@ -298,20 +303,29 @@ void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl, { #ifdef CONFIG_GBM VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl); + uint32_t x, y, width, height, backing_width, backing_height, texture; + bool y0_top; gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area)); egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - gd_gl_area_scanout_texture(dcl, dmabuf->texture, - dmabuf->y0_top, - dmabuf->backing_width, dmabuf->backing_height, - dmabuf->x, dmabuf->y, dmabuf->width, - dmabuf->height, NULL); + x = qemu_dmabuf_get_x(dmabuf); + y = qemu_dmabuf_get_y(dmabuf); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + backing_width = qemu_dmabuf_get_backing_width(dmabuf); + backing_height = qemu_dmabuf_get_backing_height(dmabuf); + y0_top = qemu_dmabuf_get_y0_top(dmabuf); - if (dmabuf->allow_fences) { + gd_gl_area_scanout_texture(dcl, texture, y0_top, + backing_width, backing_height, + x, y, width, height, NULL); + + if (qemu_dmabuf_get_allow_fences(dmabuf)) { vc->gfx.guest_fb.dmabuf = dmabuf; } #endif @@ -596,11 +596,15 @@ void gd_hw_gl_flushed(void *vcon) { VirtualConsole *vc = vcon; QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf; + int fence_fd; - qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL); - close(dmabuf->fence_fd); - dmabuf->fence_fd = -1; - graphic_hw_gl_block(vc->gfx.dcl.con, false); + fence_fd = qemu_dmabuf_get_fence_fd(dmabuf); + if (fence_fd >= 0) { + qemu_set_fd_handler(fence_fd, NULL, NULL, NULL); + close(fence_fd); + qemu_dmabuf_set_fence_fd(dmabuf, -1); + graphic_hw_gl_block(vc->gfx.dcl.con, false); + } } /** DisplayState Callbacks (opengl version) **/ @@ -887,7 +891,7 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, int x, y; int mx, my; int fbh, fbw; - int ww, wh, ws; + int ww, wh; if (!vc->gfx.ds) { return TRUE; @@ -895,11 +899,15 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x; fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y; - ww = gtk_widget_get_allocated_width(widget); wh = gtk_widget_get_allocated_height(widget); - ws = gtk_widget_get_scale_factor(widget); + /* + * `widget` may not have the same size with the frame buffer. + * In such cases, some paddings are needed around the `vc`. + * To achieve that, `vc` will be displayed at (mx, my) + * so that it is displayed at the center of the widget. + */ mx = my = 0; if (ww > fbw) { mx = (ww - fbw) / 2; @@ -908,8 +916,14 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, my = (wh - fbh) / 2; } - x = (motion->x - mx) / vc->gfx.scale_x * ws; - y = (motion->y - my) / vc->gfx.scale_y * ws; + /* + * `motion` is reported in `widget` coordinates + * so translating it to the coordinates in `vc`. + */ + x = (motion->x - mx) / vc->gfx.scale_x; + y = (motion->y - my) / vc->gfx.scale_y; + + trace_gd_motion_event(ww, wh, gtk_widget_get_scale_factor(widget), x, y); if (qemu_input_is_absolute(vc->gfx.dcl.con)) { if (x < 0 || y < 0 || diff --git a/ui/meson.build b/ui/meson.build index a5ce22a678..5d89986b0e 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -7,6 +7,7 @@ system_ss.add(files( 'clipboard.c', 'console.c', 'cursor.c', + 'dmabuf.c', 'input-keymap.c', 'input-legacy.c', 'input-barrier.c', @@ -874,6 +874,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); #endif SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + SDL_EnableScreenSaver(); memset(&info, 0, sizeof(info)); SDL_VERSION(&info.version); diff --git a/ui/spice-display.c b/ui/spice-display.c index 6eb98a5a5c..8a8472d029 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -976,6 +976,7 @@ static void qemu_spice_gl_cursor_dmabuf(DisplayChangeListener *dcl, uint32_t hot_x, uint32_t hot_y) { SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); + uint32_t width, height, texture; ssd->have_hot = have_hot; ssd->hot_x = hot_x; @@ -984,11 +985,13 @@ static void qemu_spice_gl_cursor_dmabuf(DisplayChangeListener *dcl, trace_qemu_spice_gl_cursor(ssd->qxl.id, dmabuf != NULL, have_hot); if (dmabuf) { egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } - egl_fb_setup_for_tex(&ssd->cursor_fb, dmabuf->width, dmabuf->height, - dmabuf->texture, false); + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + egl_fb_setup_for_tex(&ssd->cursor_fb, width, height, texture, false); } else { egl_fb_destroy(&ssd->cursor_fb); } @@ -1026,6 +1029,7 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl, bool y_0_top = false; /* FIXME */ uint64_t cookie; int fd; + uint32_t width, height, texture; if (!ssd->have_scanout) { return; @@ -1042,41 +1046,45 @@ static void qemu_spice_gl_update(DisplayChangeListener *dcl, if (ssd->guest_dmabuf_refresh) { QemuDmaBuf *dmabuf = ssd->guest_dmabuf; + width = qemu_dmabuf_get_width(dmabuf); + height = qemu_dmabuf_get_height(dmabuf); + if (render_cursor) { egl_dmabuf_import_texture(dmabuf); - if (!dmabuf->texture) { + texture = qemu_dmabuf_get_texture(dmabuf); + if (!texture) { return; } /* source framebuffer */ - egl_fb_setup_for_tex(&ssd->guest_fb, - dmabuf->width, dmabuf->height, - dmabuf->texture, false); + egl_fb_setup_for_tex(&ssd->guest_fb, width, height, + texture, false); /* dest framebuffer */ - if (ssd->blit_fb.width != dmabuf->width || - ssd->blit_fb.height != dmabuf->height) { - trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, dmabuf->width, - dmabuf->height); + if (ssd->blit_fb.width != width || + ssd->blit_fb.height != height) { + trace_qemu_spice_gl_render_dmabuf(ssd->qxl.id, width, + height); egl_fb_destroy(&ssd->blit_fb); egl_fb_setup_new_tex(&ssd->blit_fb, - dmabuf->width, dmabuf->height); + width, height); fd = egl_get_fd_for_texture(ssd->blit_fb.texture, &stride, &fourcc, NULL); - spice_qxl_gl_scanout(&ssd->qxl, fd, - dmabuf->width, dmabuf->height, + spice_qxl_gl_scanout(&ssd->qxl, fd, width, height, stride, fourcc, false); } } else { - trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id, - dmabuf->width, dmabuf->height); + stride = qemu_dmabuf_get_stride(dmabuf); + fourcc = qemu_dmabuf_get_fourcc(dmabuf); + y_0_top = qemu_dmabuf_get_y0_top(dmabuf); + fd = qemu_dmabuf_dup_fd(dmabuf); + + trace_qemu_spice_gl_forward_dmabuf(ssd->qxl.id, width, height); /* note: spice server will close the fd, so hand over a dup */ - spice_qxl_gl_scanout(&ssd->qxl, dup(dmabuf->fd), - dmabuf->width, dmabuf->height, - dmabuf->stride, dmabuf->fourcc, - dmabuf->y0_top); + spice_qxl_gl_scanout(&ssd->qxl, fd, width, height, + stride, fourcc, y_0_top); } - qemu_spice_gl_monitor_config(ssd, 0, 0, dmabuf->width, dmabuf->height); + qemu_spice_gl_monitor_config(ssd, 0, 0, width, height); ssd->guest_dmabuf_refresh = false; } diff --git a/ui/trace-events b/ui/trace-events index e6a2894303..69ff22955d 100644 --- a/ui/trace-events +++ b/ui/trace-events @@ -28,6 +28,7 @@ gd_ungrab(const char *tab, const char *device) "tab=%s, dev=%s" gd_keymap_windowing(const char *name) "backend=%s" gd_gl_area_create_context(void *ctx, int major, int minor) "ctx=%p, major=%d, minor=%d" gd_gl_area_destroy_context(void *ctx, void *current_ctx) "ctx=%p, current_ctx=%p" +gd_motion_event(int ww, int wh, int ws, int x, int y) "ww=%d, wh=%d, ws=%d, x=%d, y=%d" # vnc-auth-sasl.c # vnc-auth-vencrypt.c @@ -3734,11 +3734,6 @@ static int vnc_display_get_address(const char *addrstr, addr->type = SOCKET_ADDRESS_TYPE_UNIX; addr->u.q_unix.path = g_strdup(addrstr + 5); - if (websocket) { - error_setg(errp, "UNIX sockets not supported with websock"); - goto cleanup; - } - if (to) { error_setg(errp, "Port range not support with UNIX socket"); goto cleanup; |