From: Marc-André Lureau <marcandre.lur...@redhat.com> Implement a fallback path for region 2D update.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- ui/dbus-listener.c | 62 ++++++++++++++++++++++++++++++---------------- ui/meson.build | 2 +- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/ui/dbus-listener.c b/ui/dbus-listener.c index 30917271ab..f773c40685 100644 --- a/ui/dbus-listener.c +++ b/ui/dbus-listener.c @@ -562,13 +562,51 @@ static void dbus_gl_gfx_update(DisplayChangeListener *dcl, } #endif +static void dbus_gfx_update_sub(DBusDisplayListener *ddl, + int x, int y, int w, int h) +{ + pixman_image_t *img; + size_t stride; + GVariant *v_data; + + /* make a copy, since gvariant only handles linear data */ + stride = w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(ddl->ds)), 8); + img = pixman_image_create_bits(surface_format(ddl->ds), + w, h, NULL, stride); +#ifdef CONFIG_PIXMAN + pixman_image_composite(PIXMAN_OP_SRC, ddl->ds->image, NULL, img, + x, y, 0, 0, 0, 0, w, h); +#else + { + uint8_t *src = pixman_image_get_data(ddl->ds->image); + uint8_t *dst = pixman_image_get_data(img); + int bp = PIXMAN_FORMAT_BPP(surface_format(ddl->ds)) / 8; + int hh; + + for (hh = 0; hh < h; hh++) { + memcpy(&dst[stride * hh], &src[surface_stride(ddl->ds) * (hh + y) + x * bp], stride); + } + } +#endif + v_data = g_variant_new_from_data( + G_VARIANT_TYPE("ay"), + pixman_image_get_data(img), + pixman_image_get_stride(img) * h, + TRUE, + (GDestroyNotify)pixman_image_unref, + img); + qemu_dbus_display1_listener_call_update(ddl->proxy, + x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(img), + v_data, + G_DBUS_CALL_FLAGS_NONE, + DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); +} + static void dbus_gfx_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl); - pixman_image_t *img; GVariant *v_data; - size_t stride; assert(ddl->ds); @@ -605,25 +643,7 @@ static void dbus_gfx_update(DisplayChangeListener *dcl, return; } - /* make a copy, since gvariant only handles linear data */ - stride = w * DIV_ROUND_UP(PIXMAN_FORMAT_BPP(surface_format(ddl->ds)), 8); - img = pixman_image_create_bits(surface_format(ddl->ds), - w, h, NULL, stride); - pixman_image_composite(PIXMAN_OP_SRC, ddl->ds->image, NULL, img, - x, y, 0, 0, 0, 0, w, h); - - v_data = g_variant_new_from_data( - G_VARIANT_TYPE("ay"), - pixman_image_get_data(img), - pixman_image_get_stride(img) * h, - TRUE, - (GDestroyNotify)pixman_image_unref, - img); - qemu_dbus_display1_listener_call_update(ddl->proxy, - x, y, w, h, pixman_image_get_stride(img), pixman_image_get_format(img), - v_data, - G_DBUS_CALL_FLAGS_NONE, - DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL); + dbus_gfx_update_sub(ddl, x, y, w, h); } #ifdef CONFIG_OPENGL diff --git a/ui/meson.build b/ui/meson.build index 40dff7b3e0..dec2d471cc 100644 --- a/ui/meson.build +++ b/ui/meson.build @@ -93,7 +93,7 @@ if dbus_display '--generate-c-code', '@BASENAME@']) dbus_display1_lib = static_library('dbus-display1', dbus_display1, dependencies: gio) dbus_display1_dep = declare_dependency(link_with: dbus_display1_lib, include_directories: include_directories('.')) - dbus_ss.add(when: [gio, pixman, dbus_display1_dep], + dbus_ss.add(when: [gio, dbus_display1_dep], if_true: [files( 'dbus-chardev.c', 'dbus-clipboard.c', -- 2.41.0