Skip to content

Commit

Permalink
ui/dbus: do not require PIXMAN
Browse files Browse the repository at this point in the history
Implement a fallback path for region 2D update.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
  • Loading branch information
elmarco committed Nov 7, 2023
1 parent da554e1 commit 949c084
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 29 deletions.
90 changes: 63 additions & 27 deletions ui/dbus-listener.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@
#include "qapi/error.h"
#include "sysemu/sysemu.h"
#include "dbus.h"
#ifdef CONFIG_OPENGL
#include <pixman.h>
#endif
#ifdef G_OS_UNIX
#include <gio/gunixfdlist.h>
#endif
Expand All @@ -41,6 +38,7 @@
#include "ui/shader.h"
#include "ui/egl-helpers.h"
#include "ui/egl-context.h"
#include "ui/qemu-pixman.h"
#endif
#include "trace.h"

Expand All @@ -62,9 +60,11 @@ struct _DBusDisplayListener {

QemuDBusDisplay1Listener *proxy;

#ifdef CONFIG_OPENGL
#ifdef CONFIG_PIXMAN
/* Keep track of the damage region */
pixman_region32_t gl_damage;
#else
int gl_damage;
#endif

DisplayChangeListener dcl;
Expand Down Expand Up @@ -545,6 +545,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl)
return;
}

#ifdef CONFIG_PIXMAN
int n_rects = pixman_region32_n_rects(&ddl->gl_damage);

for (int i = 0; i < n_rects; i++) {
Expand All @@ -555,6 +556,13 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl)
box->x2 - box->x1, box->y2 - box->y1);
}
pixman_region32_clear(&ddl->gl_damage);
#else
if (ddl->gl_damage) {
dbus_call_update_gl(dcl, 0, 0,
surface_width(ddl->ds), surface_height(ddl->ds));
ddl->gl_damage = 0;
}
#endif
}
#endif /* OPENGL */

Expand All @@ -569,20 +577,64 @@ static void dbus_gl_gfx_update(DisplayChangeListener *dcl,
{
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);

#ifdef CONFIG_PIXMAN
pixman_region32_t rect_region;
pixman_region32_init_rect(&rect_region, x, y, w, h);
pixman_region32_union(&ddl->gl_damage, &ddl->gl_damage, &rect_region);
pixman_region32_fini(&rect_region);
#else
ddl->gl_damage++;
#endif
}
#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 = (uint8_t *)pixman_image_get_data(ddl->ds->image);
uint8_t *dst = (uint8_t *)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);

Expand Down Expand Up @@ -619,25 +671,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
Expand Down Expand Up @@ -751,8 +785,10 @@ dbus_display_listener_dispose(GObject *object)
g_clear_object(&ddl->map_proxy);
g_clear_object(&ddl->d3d11_proxy);
g_clear_pointer(&ddl->peer_process, CloseHandle);
#ifdef CONFIG_OPENGL
#ifdef CONFIG_PIXMAN
pixman_region32_fini(&ddl->gl_damage);
#endif
#ifdef CONFIG_OPENGL
egl_fb_destroy(&ddl->fb);
#endif
#endif
Expand Down Expand Up @@ -787,7 +823,7 @@ dbus_display_listener_class_init(DBusDisplayListenerClass *klass)
static void
dbus_display_listener_init(DBusDisplayListener *ddl)
{
#ifdef CONFIG_OPENGL
#ifdef CONFIG_PIXMAN
pixman_region32_init(&ddl->gl_damage);
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions ui/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ 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',
'dbus-console.c',
'dbus-error.c',
'dbus-listener.c',
'dbus.c',
), opengl, gbm])
), opengl, gbm, pixman])
ui_modules += {'dbus' : dbus_ss}
endif

Expand Down

0 comments on commit 949c084

Please sign in to comment.