ui/surface: allocate shared memory on !win32
Use qemu_memfd_alloc() to allocate the display surface memory, which will fallback on tmpfile/mmap() on systems without memfd, and allow to share the display with other processes. This is similar to how display memory is allocated on win32 since commit 09b4c198 ("console/win32: allocate shareable display surface"). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com> Message-ID: <20241008125028.1177932-13-marcandre.lureau@redhat.com>
This commit is contained in:
parent
28a3ca0478
commit
ec818df000
@ -26,6 +26,9 @@ typedef struct DisplaySurface {
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
uint32_t handle_offset;
|
uint32_t handle_offset;
|
||||||
|
#else
|
||||||
|
int shmfd;
|
||||||
|
uint32_t shmfd_offset;
|
||||||
#endif
|
#endif
|
||||||
} DisplaySurface;
|
} DisplaySurface;
|
||||||
|
|
||||||
@ -40,6 +43,9 @@ DisplaySurface *qemu_create_placeholder_surface(int w, int h,
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void qemu_displaysurface_win32_set_handle(DisplaySurface *surface,
|
void qemu_displaysurface_win32_set_handle(DisplaySurface *surface,
|
||||||
HANDLE h, uint32_t offset);
|
HANDLE h, uint32_t offset);
|
||||||
|
#else
|
||||||
|
void qemu_displaysurface_set_shmfd(DisplaySurface *surface,
|
||||||
|
int shmfd, uint32_t offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DisplaySurface *qemu_create_displaysurface(int width, int height);
|
DisplaySurface *qemu_create_displaysurface(int width, int height);
|
||||||
|
28
ui/console.c
28
ui/console.c
@ -37,6 +37,7 @@
|
|||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
#include "qemu/memfd.h"
|
||||||
|
|
||||||
#include "console-priv.h"
|
#include "console-priv.h"
|
||||||
|
|
||||||
@ -461,6 +462,15 @@ void qemu_displaysurface_win32_set_handle(DisplaySurface *surface,
|
|||||||
surface->handle = h;
|
surface->handle = h;
|
||||||
surface->handle_offset = offset;
|
surface->handle_offset = offset;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void qemu_displaysurface_set_shmfd(DisplaySurface *surface,
|
||||||
|
int shmfd, uint32_t offset)
|
||||||
|
{
|
||||||
|
assert(surface->shmfd == -1);
|
||||||
|
|
||||||
|
surface->shmfd = shmfd;
|
||||||
|
surface->shmfd_offset = offset;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DisplaySurface *qemu_create_displaysurface(int width, int height)
|
DisplaySurface *qemu_create_displaysurface(int width, int height)
|
||||||
@ -469,12 +479,16 @@ DisplaySurface *qemu_create_displaysurface(int width, int height)
|
|||||||
void *bits = NULL;
|
void *bits = NULL;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HANDLE handle = NULL;
|
HANDLE handle = NULL;
|
||||||
|
#else
|
||||||
|
int shmfd = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
trace_displaysurface_create(width, height);
|
trace_displaysurface_create(width, height);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
bits = qemu_win32_map_alloc(width * height * 4, &handle, &error_abort);
|
bits = qemu_win32_map_alloc(width * height * 4, &handle, &error_abort);
|
||||||
|
#else
|
||||||
|
bits = qemu_memfd_alloc("displaysurface", width * height * 4, 0, &shmfd, &error_abort);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
surface = qemu_create_displaysurface_from(
|
surface = qemu_create_displaysurface_from(
|
||||||
@ -486,9 +500,13 @@ DisplaySurface *qemu_create_displaysurface(int width, int height)
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
qemu_displaysurface_win32_set_handle(surface, handle, 0);
|
qemu_displaysurface_win32_set_handle(surface, handle, 0);
|
||||||
pixman_image_set_destroy_function(surface->image,
|
void *data = handle;
|
||||||
qemu_pixman_shared_image_destroy, handle);
|
#else
|
||||||
|
qemu_displaysurface_set_shmfd(surface, shmfd, 0);
|
||||||
|
void *data = GINT_TO_POINTER(shmfd);
|
||||||
#endif
|
#endif
|
||||||
|
pixman_image_set_destroy_function(surface->image, qemu_pixman_shared_image_destroy, data);
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,6 +517,9 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
|
|||||||
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
||||||
|
|
||||||
trace_displaysurface_create_from(surface, width, height, format);
|
trace_displaysurface_create_from(surface, width, height, format);
|
||||||
|
#ifndef WIN32
|
||||||
|
surface->shmfd = -1;
|
||||||
|
#endif
|
||||||
surface->image = pixman_image_create_bits(format,
|
surface->image = pixman_image_create_bits(format,
|
||||||
width, height,
|
width, height,
|
||||||
(void *)data, linesize);
|
(void *)data, linesize);
|
||||||
@ -512,6 +533,9 @@ DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image)
|
|||||||
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
DisplaySurface *surface = g_new0(DisplaySurface, 1);
|
||||||
|
|
||||||
trace_displaysurface_create_pixman(surface);
|
trace_displaysurface_create_pixman(surface);
|
||||||
|
#ifndef WIN32
|
||||||
|
surface->shmfd = -1;
|
||||||
|
#endif
|
||||||
surface->image = pixman_image_ref(image);
|
surface->image = pixman_image_ref(image);
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user