diff options
Diffstat (limited to 'ui')
| -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 |
14 files changed, 444 insertions, 136 deletions
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 diff --git a/ui/gtk.c b/ui/gtk.c index 810d7fc796..93b13b7a30 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -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', diff --git a/ui/sdl2.c b/ui/sdl2.c index 4971963f00..0a0eb5a42d 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.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 diff --git a/ui/vnc.c b/ui/vnc.c index b3fd78022b..dd530f04e5 100644 --- a/ui/vnc.c +++ b/ui/vnc.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; |