virtio-gpu + ui: fence syncronization.
qxl: unbreak live migration. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmFC3HMACgkQTLbY7tPo cTiuyRAAmNsd/aC90DRGYCvT1lSYt/ZTvDF+NRJqxovvsP3veBbvyhYZtNpmmjtx s5vRvYoo7Q9Zcu2E5n+Qqwy2LbRRKGDpcftc/KzTZzQXLATUh4NvsL/80aYtyCrb VxlmZK8LqO8G9dmwoN7fbKMsMGjT9MnzCsPWzicyTKg6j8/lPUyvpqaoorh9/Ml5 ah3MFMdsLGL0trTR4pPRxswZH7QQ1V9/lI5alvXFzaqgsjkDZZ8+PS2Onnls+Sc5 PXAAM3+yWXufE9cDE6m8LR0/KDQAwP743ISECD7v0cJ2Ji2Aeb6o6s+k84JQSQml MJ5D4M34qbNk3+E/oqpvqavlcxkZyG7qGJEysZmGrmCeWzHVumUN/BHbpDICYqWf aj9q3OXmIKEiTxvpDfngJ28QIlJa7+n+DmvNzjzcpAIK5Zc5pZ0foARrVMUyAlz6 1L98miVdLtKDLLeZkQ6torokElFaSbSCuTC6119VLsbZt0nfjGYTxYk5v4DhVaUj QjdAHEa4Bwh28/1V5nP8UkGsiHGSe43PjS1TzOlUYZdNzqJeD7TVEOlSbNqiR1+N kv3V3gvgX9zrWR4QCAwn3D+kP0qhuHxCw/dN4Ms/l48kTQ9t/F3eJIDQW1fkENnZ C+gPUyGrol5J2Fnt43bgtjCpup4w/axt6QnxgVY148KeMzR6WHQ= =KiDa -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/vga-20210916-pull-request' into staging virtio-gpu + ui: fence syncronization. qxl: unbreak live migration. # gpg: Signature made Thu 16 Sep 2021 06:56:03 BST # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20210916-pull-request: virtio-gpu: Add gl_flushed callback ui/gtk-egl: Wait for the draw signal for dmabuf blobs ui: Create sync objects and fences only for blobs ui/egl: Add egl helpers to help with synchronization ui/gtk: Create a common release_dmabuf helper qxl: fix pre-save logic Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
63cf61256a
@ -2252,7 +2252,7 @@ static int qxl_pre_save(void *opaque)
|
|||||||
} else {
|
} else {
|
||||||
d->last_release_offset = (uint8_t *)d->last_release - ram_start;
|
d->last_release_offset = (uint8_t *)d->last_release - ram_start;
|
||||||
}
|
}
|
||||||
if (d->last_release_offset < d->vga.vram_size) {
|
if (d->last_release_offset >= d->vga.vram_size) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ static VGPUDMABuf
|
|||||||
dmabuf->buf.stride = fb->stride;
|
dmabuf->buf.stride = fb->stride;
|
||||||
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
|
dmabuf->buf.fourcc = qemu_pixman_to_drm_format(fb->format);
|
||||||
dmabuf->buf.fd = res->dmabuf_fd;
|
dmabuf->buf.fd = res->dmabuf_fd;
|
||||||
|
dmabuf->buf.allow_fences = true;
|
||||||
|
|
||||||
dmabuf->scanout_id = scanout_id;
|
dmabuf->scanout_id = scanout_id;
|
||||||
QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
|
QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next);
|
||||||
|
@ -985,8 +985,10 @@ void virtio_gpu_simple_process_cmd(VirtIOGPU *g,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!cmd->finished) {
|
if (!cmd->finished) {
|
||||||
virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error :
|
if (!g->parent_obj.renderer_blocked) {
|
||||||
VIRTIO_GPU_RESP_OK_NODATA);
|
virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error :
|
||||||
|
VIRTIO_GPU_RESP_OK_NODATA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,6 +1044,30 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g)
|
|||||||
g->processing_cmdq = false;
|
g->processing_cmdq = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_gpu_process_fenceq(VirtIOGPU *g)
|
||||||
|
{
|
||||||
|
struct virtio_gpu_ctrl_command *cmd, *tmp;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) {
|
||||||
|
trace_virtio_gpu_fence_resp(cmd->cmd_hdr.fence_id);
|
||||||
|
virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NODATA);
|
||||||
|
QTAILQ_REMOVE(&g->fenceq, cmd, next);
|
||||||
|
g_free(cmd);
|
||||||
|
g->inflight--;
|
||||||
|
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
|
||||||
|
fprintf(stderr, "inflight: %3d (-)\r", g->inflight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_gpu_handle_gl_flushed(VirtIOGPUBase *b)
|
||||||
|
{
|
||||||
|
VirtIOGPU *g = container_of(b, VirtIOGPU, parent_obj);
|
||||||
|
|
||||||
|
virtio_gpu_process_fenceq(g);
|
||||||
|
virtio_gpu_process_cmdq(g);
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
static void virtio_gpu_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
|
||||||
{
|
{
|
||||||
VirtIOGPU *g = VIRTIO_GPU(vdev);
|
VirtIOGPU *g = VIRTIO_GPU(vdev);
|
||||||
@ -1400,10 +1426,12 @@ static void virtio_gpu_class_init(ObjectClass *klass, void *data)
|
|||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
|
||||||
VirtIOGPUClass *vgc = VIRTIO_GPU_CLASS(klass);
|
VirtIOGPUClass *vgc = VIRTIO_GPU_CLASS(klass);
|
||||||
|
VirtIOGPUBaseClass *vgbc = &vgc->parent;
|
||||||
|
|
||||||
vgc->handle_ctrl = virtio_gpu_handle_ctrl;
|
vgc->handle_ctrl = virtio_gpu_handle_ctrl;
|
||||||
vgc->process_cmd = virtio_gpu_simple_process_cmd;
|
vgc->process_cmd = virtio_gpu_simple_process_cmd;
|
||||||
vgc->update_cursor_data = virtio_gpu_update_cursor_data;
|
vgc->update_cursor_data = virtio_gpu_update_cursor_data;
|
||||||
|
vgbc->gl_flushed = virtio_gpu_handle_gl_flushed;
|
||||||
|
|
||||||
vdc->realize = virtio_gpu_device_realize;
|
vdc->realize = virtio_gpu_device_realize;
|
||||||
vdc->reset = virtio_gpu_reset;
|
vdc->reset = virtio_gpu_reset;
|
||||||
|
@ -168,6 +168,9 @@ typedef struct QemuDmaBuf {
|
|||||||
uint64_t modifier;
|
uint64_t modifier;
|
||||||
uint32_t texture;
|
uint32_t texture;
|
||||||
bool y0_top;
|
bool y0_top;
|
||||||
|
void *sync;
|
||||||
|
int fence_fd;
|
||||||
|
bool allow_fences;
|
||||||
} QemuDmaBuf;
|
} QemuDmaBuf;
|
||||||
|
|
||||||
typedef struct DisplayState DisplayState;
|
typedef struct DisplayState DisplayState;
|
||||||
|
@ -19,6 +19,7 @@ typedef struct egl_fb {
|
|||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLuint framebuffer;
|
GLuint framebuffer;
|
||||||
bool delete_texture;
|
bool delete_texture;
|
||||||
|
QemuDmaBuf *dmabuf;
|
||||||
} egl_fb;
|
} egl_fb;
|
||||||
|
|
||||||
void egl_fb_destroy(egl_fb *fb);
|
void egl_fb_destroy(egl_fb *fb);
|
||||||
@ -45,6 +46,8 @@ int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc,
|
|||||||
|
|
||||||
void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf);
|
void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf);
|
||||||
void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
|
void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
|
||||||
|
void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf);
|
||||||
|
void egl_dmabuf_create_fence(QemuDmaBuf *dmabuf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ extern bool gtk_use_gl_area;
|
|||||||
/* ui/gtk.c */
|
/* ui/gtk.c */
|
||||||
void gd_update_windowsize(VirtualConsole *vc);
|
void gd_update_windowsize(VirtualConsole *vc);
|
||||||
int gd_monitor_update_interval(GtkWidget *widget);
|
int gd_monitor_update_interval(GtkWidget *widget);
|
||||||
|
void gd_hw_gl_flushed(void *vc);
|
||||||
|
|
||||||
/* ui/gtk-egl.c */
|
/* ui/gtk-egl.c */
|
||||||
void gd_egl_init(VirtualConsole *vc);
|
void gd_egl_init(VirtualConsole *vc);
|
||||||
@ -181,8 +182,8 @@ void gd_egl_cursor_dmabuf(DisplayChangeListener *dcl,
|
|||||||
uint32_t hot_x, uint32_t hot_y);
|
uint32_t hot_x, uint32_t hot_y);
|
||||||
void gd_egl_cursor_position(DisplayChangeListener *dcl,
|
void gd_egl_cursor_position(DisplayChangeListener *dcl,
|
||||||
uint32_t pos_x, uint32_t pos_y);
|
uint32_t pos_x, uint32_t pos_y);
|
||||||
void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
|
void gd_egl_flush(DisplayChangeListener *dcl,
|
||||||
QemuDmaBuf *dmabuf);
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||||
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
||||||
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h);
|
||||||
void gtk_egl_init(DisplayGLMode mode);
|
void gtk_egl_init(DisplayGLMode mode);
|
||||||
|
@ -287,6 +287,32 @@ void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf)
|
|||||||
dmabuf->texture = 0;
|
dmabuf->texture = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void egl_dmabuf_create_sync(QemuDmaBuf *dmabuf)
|
||||||
|
{
|
||||||
|
EGLSyncKHR sync;
|
||||||
|
|
||||||
|
if (epoxy_has_egl_extension(qemu_egl_display,
|
||||||
|
"EGL_KHR_fence_sync") &&
|
||||||
|
epoxy_has_egl_extension(qemu_egl_display,
|
||||||
|
"EGL_ANDROID_native_fence_sync")) {
|
||||||
|
sync = eglCreateSyncKHR(qemu_egl_display,
|
||||||
|
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
|
||||||
|
if (sync != EGL_NO_SYNC_KHR) {
|
||||||
|
dmabuf->sync = 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_GBM */
|
#endif /* CONFIG_GBM */
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
48
ui/gtk-egl.c
48
ui/gtk-egl.c
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/main-loop.h"
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
@ -94,6 +95,18 @@ void gd_egl_draw(VirtualConsole *vc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
|
#ifdef CONFIG_GBM
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||||
|
|
||||||
|
egl_dmabuf_create_fence(dmabuf);
|
||||||
|
if (dmabuf->fence_fd > 0) {
|
||||||
|
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +222,8 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
|
|||||||
QemuDmaBuf *dmabuf)
|
QemuDmaBuf *dmabuf)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_GBM
|
#ifdef CONFIG_GBM
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
egl_dmabuf_import_texture(dmabuf);
|
egl_dmabuf_import_texture(dmabuf);
|
||||||
if (!dmabuf->texture) {
|
if (!dmabuf->texture) {
|
||||||
return;
|
return;
|
||||||
@ -217,6 +232,10 @@ void gd_egl_scanout_dmabuf(DisplayChangeListener *dcl,
|
|||||||
gd_egl_scanout_texture(dcl, dmabuf->texture,
|
gd_egl_scanout_texture(dcl, dmabuf->texture,
|
||||||
false, dmabuf->width, dmabuf->height,
|
false, dmabuf->width, dmabuf->height,
|
||||||
0, 0, dmabuf->width, dmabuf->height);
|
0, 0, dmabuf->width, dmabuf->height);
|
||||||
|
|
||||||
|
if (dmabuf->allow_fences) {
|
||||||
|
vc->gfx.guest_fb.dmabuf = dmabuf;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,14 +268,6 @@ void gd_egl_cursor_position(DisplayChangeListener *dcl,
|
|||||||
vc->gfx.cursor_y = pos_y * vc->gfx.scale_y;
|
vc->gfx.cursor_y = pos_y * vc->gfx.scale_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gd_egl_release_dmabuf(DisplayChangeListener *dcl,
|
|
||||||
QemuDmaBuf *dmabuf)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_GBM
|
|
||||||
egl_dmabuf_release_texture(dmabuf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
||||||
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||||
{
|
{
|
||||||
@ -289,9 +300,30 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
|||||||
egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
|
egl_fb_blit(&vc->gfx.win_fb, &vc->gfx.guest_fb, !vc->gfx.y0_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_GBM
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
|
eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gd_egl_flush(DisplayChangeListener *dcl,
|
||||||
|
uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
GtkWidget *area = vc->gfx.drawing_area;
|
||||||
|
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||||
|
gtk_widget_queue_draw_area(area, x, y, w, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gd_egl_scanout_flush(&vc->gfx.dcl, x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
void gtk_egl_init(DisplayGLMode mode)
|
void gtk_egl_init(DisplayGLMode mode)
|
||||||
{
|
{
|
||||||
GdkDisplay *gdk_display = gdk_display_get_default();
|
GdkDisplay *gdk_display = gdk_display_get_default();
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/main-loop.h"
|
||||||
|
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
|
||||||
@ -71,7 +72,25 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
|||||||
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_GBM
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
egl_dmabuf_create_sync(vc->gfx.guest_fb.dmabuf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
|
#ifdef CONFIG_GBM
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||||
|
|
||||||
|
egl_dmabuf_create_fence(dmabuf);
|
||||||
|
if (dmabuf->fence_fd > 0) {
|
||||||
|
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +232,9 @@ void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
|
|||||||
{
|
{
|
||||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||||
|
|
||||||
|
if (vc->gfx.guest_fb.dmabuf) {
|
||||||
|
graphic_hw_gl_block(vc->gfx.dcl.con, true);
|
||||||
|
}
|
||||||
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,6 +253,10 @@ void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
|
|||||||
gd_gl_area_scanout_texture(dcl, dmabuf->texture,
|
gd_gl_area_scanout_texture(dcl, dmabuf->texture,
|
||||||
false, dmabuf->width, dmabuf->height,
|
false, dmabuf->width, dmabuf->height,
|
||||||
0, 0, dmabuf->width, dmabuf->height);
|
0, 0, dmabuf->width, dmabuf->height);
|
||||||
|
|
||||||
|
if (dmabuf->allow_fences) {
|
||||||
|
vc->gfx.guest_fb.dmabuf = dmabuf;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
ui/gtk.c
26
ui/gtk.c
@ -36,6 +36,7 @@
|
|||||||
#include "qapi/qapi-commands-machine.h"
|
#include "qapi/qapi-commands-machine.h"
|
||||||
#include "qapi/qapi-commands-misc.h"
|
#include "qapi/qapi-commands-misc.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
|
#include "qemu/main-loop.h"
|
||||||
|
|
||||||
#include "ui/console.h"
|
#include "ui/console.h"
|
||||||
#include "ui/gtk.h"
|
#include "ui/gtk.h"
|
||||||
@ -575,6 +576,26 @@ static bool gd_has_dmabuf(DisplayChangeListener *dcl)
|
|||||||
return vc->gfx.has_dmabuf;
|
return vc->gfx.has_dmabuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gd_gl_release_dmabuf(DisplayChangeListener *dcl,
|
||||||
|
QemuDmaBuf *dmabuf)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_GBM
|
||||||
|
egl_dmabuf_release_texture(dmabuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void gd_hw_gl_flushed(void *vcon)
|
||||||
|
{
|
||||||
|
VirtualConsole *vc = vcon;
|
||||||
|
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||||
|
|
||||||
|
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||||
|
graphic_hw_gl_flushed(vc->gfx.dcl.con);
|
||||||
|
qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
|
||||||
|
close(dmabuf->fence_fd);
|
||||||
|
dmabuf->fence_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/** DisplayState Callbacks (opengl version) **/
|
/** DisplayState Callbacks (opengl version) **/
|
||||||
|
|
||||||
static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
||||||
@ -593,6 +614,7 @@ static const DisplayChangeListenerOps dcl_gl_area_ops = {
|
|||||||
.dpy_gl_scanout_disable = gd_gl_area_scanout_disable,
|
.dpy_gl_scanout_disable = gd_gl_area_scanout_disable,
|
||||||
.dpy_gl_update = gd_gl_area_scanout_flush,
|
.dpy_gl_update = gd_gl_area_scanout_flush,
|
||||||
.dpy_gl_scanout_dmabuf = gd_gl_area_scanout_dmabuf,
|
.dpy_gl_scanout_dmabuf = gd_gl_area_scanout_dmabuf,
|
||||||
|
.dpy_gl_release_dmabuf = gd_gl_release_dmabuf,
|
||||||
.dpy_has_dmabuf = gd_has_dmabuf,
|
.dpy_has_dmabuf = gd_has_dmabuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -615,8 +637,8 @@ static const DisplayChangeListenerOps dcl_egl_ops = {
|
|||||||
.dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
|
.dpy_gl_scanout_dmabuf = gd_egl_scanout_dmabuf,
|
||||||
.dpy_gl_cursor_dmabuf = gd_egl_cursor_dmabuf,
|
.dpy_gl_cursor_dmabuf = gd_egl_cursor_dmabuf,
|
||||||
.dpy_gl_cursor_position = gd_egl_cursor_position,
|
.dpy_gl_cursor_position = gd_egl_cursor_position,
|
||||||
.dpy_gl_release_dmabuf = gd_egl_release_dmabuf,
|
.dpy_gl_update = gd_egl_flush,
|
||||||
.dpy_gl_update = gd_egl_scanout_flush,
|
.dpy_gl_release_dmabuf = gd_gl_release_dmabuf,
|
||||||
.dpy_has_dmabuf = gd_has_dmabuf,
|
.dpy_has_dmabuf = gd_has_dmabuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user