DisplaySurface may be free before the pixman image is freed, since the
image is refcounted and used by different objects, including pending
dbus messages.
Furthermore, setting the destroy function in
create_displaysurface_from() isn't appropriate, as it may not be used,
and may be overriden as in ramfb.
Set the destroy function when the shared handle is set, use the HANDLE
directly for destroy data, using a single common helper
qemu_pixman_win32_image_destroy().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <
20241008125028.
1177932-5-marcandre.lureau@redhat.com>
(cherry picked from commit
330ef31deb2e5461cff907488b710f5bd9cd2327)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
return height * stride;
}
-#ifdef WIN32
-static void
-win32_pixman_image_destroy(pixman_image_t *image, void *data)
-{
- HANDLE handle = data;
-
- qemu_win32_map_free(pixman_image_get_data(image), handle, &error_warn);
-}
-#endif
-
static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
bits, c2d.height ? res->hostmem / c2d.height : 0);
#ifdef WIN32
if (res->image) {
- pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle);
+ pixman_image_set_destroy_function(res->image, qemu_pixman_win32_image_destroy, res->handle);
}
#endif
}
return -EINVAL;
}
#ifdef WIN32
- pixman_image_set_destroy_function(res->image, win32_pixman_image_destroy, res->handle);
+ pixman_image_set_destroy_function(res->image, qemu_pixman_win32_image_destroy, res->handle);
#endif
res->addrs = g_new(uint64_t, res->iov_cnt);
void qemu_pixman_image_unref(pixman_image_t *image);
+void qemu_pixman_win32_image_destroy(pixman_image_t *image, void *data);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref)
#endif /* QEMU_PIXMAN_H */
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)
#ifdef WIN32
qemu_displaysurface_win32_set_handle(surface, handle, 0);
+ pixman_image_set_destroy_function(surface->image,
+ qemu_pixman_win32_image_destroy, handle);
#endif
return surface;
}
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;
}
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "ui/console.h"
#include "standard-headers/drm/drm_fourcc.h"
#include "trace.h"
pixman_image_unref(ibg);
}
#endif /* CONFIG_PIXMAN */
+
+#ifdef WIN32
+void
+qemu_pixman_win32_image_destroy(pixman_image_t *image, void *data)
+{
+ HANDLE handle = data;
+
+ qemu_win32_map_free(
+ pixman_image_get_data(image),
+ handle,
+ &error_warn
+ );
+}
+#endif