:p
atchew
Login
From: Benno Fünfstück <benno.fuenfstueck@neodyme.io> When using virtio-gpu-gl, if the guest uses hardware mouse cursor acceleration then the mouse cursor can end up being a resource with the flag Y_0_TOP set. In this case, we need to make sure to flip the cursor data such that display clients render it correctly. For example, this fixes mouse cursor rendering for wlroots-based window managers (like Sway) in Linux guests. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2315 Signed-off-by: Benno Fünfstück <benno.fuenfstueck@neodyme.io> --- hw/display/virtio-gpu-gl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index XXXXXXX..XXXXXXX 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -XXX,XX +XXX,XX @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, VirtIOGPUGL *gl = VIRTIO_GPU_GL(g); uint32_t width, height; uint32_t pixels, *data; + bool y_0_top = true; + int ret; + struct virgl_renderer_resource_info info; if (gl->renderer_state != RS_INITED) { return; @@ -XXX,XX +XXX,XX @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, return; } + memset(&info, 0, sizeof(info)); + ret = virgl_renderer_resource_get_info(resource_id, &info); + if (ret == 0) { + y_0_top = info.flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP; + } + pixels = s->current_cursor->width * s->current_cursor->height; - memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t)); + if (y_0_top) { + memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t)); + } else { + uint32_t *dst = s->current_cursor->data; + for (uint32_t y = 0; y < height; y++) { + memcpy(dst + y * width, + data + (height - 1 - y) * width, + width * sizeof(uint32_t)); + } + } free(data); } -- 2.50.1 (Apple Git-155) -- Neodyme AG Sitz der Gesellschaft / Address: Dirnismaning 55 | Halle 13 | 85748 Garching b.München Postanschrift: Rosenthaler Straße 72a | 10119 Berlin Registergericht / Registry court: München, HRB 269168 Vorstand / Management Board: Thomas Lambertz | Tobias Madl Aufsichtsratsvorsitzender / Chairman of the Supervisory Board: Hendrik Hofstadt
From: Benno Fünfstück <benno.fuenfstueck@neodyme.io> This is a fix for a bug in virglrenderer, where if the guest uses hardware mouse cursor acceleration then the mouse cursor can end up being a resource with the flag Y_0_TOP set. But virglrenderer does not honor this flag when reading the cursor data. This has been fixed in current virglrenderer master. For older virglrenderer, we need to make sure to flip the cursor data such that display clients render it correctly. For example, this fixes mouse cursor rendering for wlroots-based window managers (like Sway) in Linux guests. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2315 Signed-off-by: Benno Fünfstück <benno.fuenfstueck@neodyme.io> --- Now with a version check, since the fix for this is in virlglrenderer master so I think it is any version newer than the current one (which is 1.3.0). I copied the code from virtio-gpu-virgl.c for the version check for simplicty, if I should instead move that code for some DRY feel free to say so. hw/display/virtio-gpu-gl.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index XXXXXXX..XXXXXXX 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -XXX,XX +XXX,XX @@ #include <virglrenderer.h> +/* + * VIRGL_CHECK_VERSION available since libvirglrenderer 1.0.1 and was fixed + * in 1.1.0. Undefine bugged version of the macro and provide our own. + */ +#if defined(VIRGL_CHECK_VERSION) && \ + VIRGL_VERSION_MAJOR == 1 && VIRGL_VERSION_MINOR < 1 +#undef VIRGL_CHECK_VERSION +#endif + +#ifndef VIRGL_CHECK_VERSION +#define VIRGL_CHECK_VERSION(major, minor, micro) \ + (VIRGL_VERSION_MAJOR > (major) || \ + VIRGL_VERSION_MAJOR == (major) && VIRGL_VERSION_MINOR > (minor) || \ + VIRGL_VERSION_MAJOR == (major) && VIRGL_VERSION_MINOR == (minor) && \ + VIRGL_VERSION_MICRO >= (micro)) +#endif + +#define VIRGL_NEEDS_CURSOR_DATA_FLIP_FIX (!VIRGL_CHECK_VERSION(1, 3, 1)) + static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, struct virtio_gpu_scanout *s, uint32_t resource_id) @@ -XXX,XX +XXX,XX @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, VirtIOGPUGL *gl = VIRTIO_GPU_GL(g); uint32_t width, height; uint32_t pixels, *data; +#if VIRGL_NEEDS_CURSOR_DATA_FLIP_FIX + bool y_0_top = true; + int ret; + struct virgl_renderer_resource_info info; +#endif if (gl->renderer_state != RS_INITED) { return; @@ -XXX,XX +XXX,XX @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, return; } +#if VIRGL_NEEDS_CURSOR_DATA_FLIP_FIX + memset(&info, 0, sizeof(info)); + ret = virgl_renderer_resource_get_info(resource_id, &info); + if (ret == 0) { + y_0_top = info.flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP; + } +#endif + pixels = s->current_cursor->width * s->current_cursor->height; +#if VIRGL_NEEDS_CURSOR_DATA_FLIP_FIX + if (y_0_top) { + memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t)); + } else { + uint32_t *dst = s->current_cursor->data; + for (uint32_t y = 0; y < height; y++) { + memcpy(dst + y * width, + data + (height - 1 - y) * width, + width * sizeof(uint32_t)); + } + } +#else memcpy(s->current_cursor->data, data, pixels * sizeof(uint32_t)); +#endif free(data); } -- 2.51.2 -- Neodyme AG Sitz der Gesellschaft / Address: Dirnismaning 55 | Halle 13 | 85748 Garching b.München Postanschrift: Rosenthaler Straße 72a | 10119 Berlin Registergericht / Registry court: München, HRB 269168 Vorstand / Management Board: Thomas Lambertz | Tobias Madl Aufsichtsratsvorsitzender / Chairman of the Supervisory Board: Hendrik Hofstadt