summary refs log tree commit diff stats
path: root/ui/console.c
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2023-06-06 15:56:46 +0400
committerMarc-André Lureau <marcandre.lureau@redhat.com>2023-06-27 17:08:56 +0200
commit09b4c198b80c3f5c9c051bc8d8935668cdd206e5 (patch)
tree4b5f90d29bd863eed8e1bda300cadb5bbebec68b /ui/console.c
parent439e0164cd83bf50095e6f66bb036b43a65a68b6 (diff)
downloadfocaccia-qemu-09b4c198b80c3f5c9c051bc8d8935668cdd206e5.tar.gz
focaccia-qemu-09b4c198b80c3f5c9c051bc8d8935668cdd206e5.zip
console/win32: allocate shareable display surface
Introduce qemu_win32_map_alloc() and qemu_win32_map_free() to allocate
shared memory mapping. The handle can be used to share the mapping with
another process.

Teach qemu_create_displaysurface() to allocate shared memory. Following
patches will introduce other places for shared memory allocation.

Other patches for -display dbus will share the memory when possible with
the client, to avoid expensive memory copy between the processes.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230606115658.677673-10-marcandre.lureau@redhat.com>
Diffstat (limited to 'ui/console.c')
-rw-r--r--ui/console.c59
1 files changed, 52 insertions, 7 deletions
diff --git a/ui/console.c b/ui/console.c
index cfaa43e970..4957110723 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1513,18 +1513,59 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
     return s;
 }
 
+#ifdef WIN32
+void qemu_displaysurface_win32_set_handle(DisplaySurface *surface,
+                                          HANDLE h, uint32_t offset)
+{
+    assert(!surface->handle);
+
+    surface->handle = h;
+    surface->handle_offset = offset;
+}
+
+static void
+win32_pixman_image_destroy(pixman_image_t *image, void *data)
+{
+    DisplaySurface *surface = data;
+
+    if (!surface->handle) {
+        return;
+    }
+
+    assert(surface->handle_offset == 0);
+
+    qemu_win32_map_free(
+        pixman_image_get_data(surface->image),
+        surface->handle,
+        &error_warn
+    );
+}
+#endif
+
 DisplaySurface *qemu_create_displaysurface(int width, int height)
 {
-    DisplaySurface *surface = g_new0(DisplaySurface, 1);
+    DisplaySurface *surface;
+    void *bits = NULL;
+#ifdef WIN32
+    HANDLE handle = NULL;
+#endif
 
-    trace_displaysurface_create(surface, width, height);
-    surface->format = PIXMAN_x8r8g8b8;
-    surface->image = pixman_image_create_bits(surface->format,
-                                              width, height,
-                                              NULL, width * 4);
-    assert(surface->image != NULL);
+    trace_displaysurface_create(width, height);
+
+#ifdef WIN32
+    bits = qemu_win32_map_alloc(width * height * 4, &handle, &error_abort);
+#endif
+
+    surface = qemu_create_displaysurface_from(
+        width, height,
+        PIXMAN_x8r8g8b8,
+        width * 4, bits
+    );
     surface->flags = QEMU_ALLOCATED_FLAG;
 
+#ifdef WIN32
+    qemu_displaysurface_win32_set_handle(surface, handle, 0);
+#endif
     return surface;
 }
 
@@ -1540,6 +1581,10 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
                                               width, height,
                                               (void *)data, linesize);
     assert(surface->image != NULL);
+#ifdef WIN32
+    pixman_image_set_destroy_function(surface->image,
+                                      win32_pixman_image_destroy, surface);
+#endif
 
     return surface;
 }