|
@@ -26,9 +26,6 @@
|
|
#include "qapi/error.h"
|
|
#include "qapi/error.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "dbus.h"
|
|
#include "dbus.h"
|
|
-#ifdef CONFIG_OPENGL
|
|
|
|
-#include <pixman.h>
|
|
|
|
-#endif
|
|
|
|
#ifdef G_OS_UNIX
|
|
#ifdef G_OS_UNIX
|
|
#include <gio/gunixfdlist.h>
|
|
#include <gio/gunixfdlist.h>
|
|
#endif
|
|
#endif
|
|
@@ -41,6 +38,7 @@
|
|
#include "ui/shader.h"
|
|
#include "ui/shader.h"
|
|
#include "ui/egl-helpers.h"
|
|
#include "ui/egl-helpers.h"
|
|
#include "ui/egl-context.h"
|
|
#include "ui/egl-context.h"
|
|
|
|
+#include "ui/qemu-pixman.h"
|
|
#endif
|
|
#endif
|
|
#include "trace.h"
|
|
#include "trace.h"
|
|
|
|
|
|
@@ -62,9 +60,11 @@ struct _DBusDisplayListener {
|
|
|
|
|
|
QemuDBusDisplay1Listener *proxy;
|
|
QemuDBusDisplay1Listener *proxy;
|
|
|
|
|
|
-#ifdef CONFIG_OPENGL
|
|
|
|
|
|
+#ifdef CONFIG_PIXMAN
|
|
/* Keep track of the damage region */
|
|
/* Keep track of the damage region */
|
|
pixman_region32_t gl_damage;
|
|
pixman_region32_t gl_damage;
|
|
|
|
+#else
|
|
|
|
+ int gl_damage;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
DisplayChangeListener dcl;
|
|
DisplayChangeListener dcl;
|
|
@@ -545,6 +545,7 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PIXMAN
|
|
int n_rects = pixman_region32_n_rects(&ddl->gl_damage);
|
|
int n_rects = pixman_region32_n_rects(&ddl->gl_damage);
|
|
|
|
|
|
for (int i = 0; i < n_rects; i++) {
|
|
for (int i = 0; i < n_rects; i++) {
|
|
@@ -555,6 +556,13 @@ static void dbus_gl_refresh(DisplayChangeListener *dcl)
|
|
box->x2 - box->x1, box->y2 - box->y1);
|
|
box->x2 - box->x1, box->y2 - box->y1);
|
|
}
|
|
}
|
|
pixman_region32_clear(&ddl->gl_damage);
|
|
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 */
|
|
#endif /* OPENGL */
|
|
|
|
|
|
@@ -569,20 +577,64 @@ static void dbus_gl_gfx_update(DisplayChangeListener *dcl,
|
|
{
|
|
{
|
|
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
|
|
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PIXMAN
|
|
pixman_region32_t rect_region;
|
|
pixman_region32_t rect_region;
|
|
pixman_region32_init_rect(&rect_region, x, y, w, h);
|
|
pixman_region32_init_rect(&rect_region, x, y, w, h);
|
|
pixman_region32_union(&ddl->gl_damage, &ddl->gl_damage, &rect_region);
|
|
pixman_region32_union(&ddl->gl_damage, &ddl->gl_damage, &rect_region);
|
|
pixman_region32_fini(&rect_region);
|
|
pixman_region32_fini(&rect_region);
|
|
|
|
+#else
|
|
|
|
+ ddl->gl_damage++;
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
#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,
|
|
static void dbus_gfx_update(DisplayChangeListener *dcl,
|
|
int x, int y, int w, int h)
|
|
int x, int y, int w, int h)
|
|
{
|
|
{
|
|
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
|
|
DBusDisplayListener *ddl = container_of(dcl, DBusDisplayListener, dcl);
|
|
- pixman_image_t *img;
|
|
|
|
GVariant *v_data;
|
|
GVariant *v_data;
|
|
- size_t stride;
|
|
|
|
|
|
|
|
assert(ddl->ds);
|
|
assert(ddl->ds);
|
|
|
|
|
|
@@ -619,25 +671,7 @@ static void dbus_gfx_update(DisplayChangeListener *dcl,
|
|
return;
|
|
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
|
|
#ifdef CONFIG_OPENGL
|
|
@@ -751,8 +785,10 @@ dbus_display_listener_dispose(GObject *object)
|
|
g_clear_object(&ddl->map_proxy);
|
|
g_clear_object(&ddl->map_proxy);
|
|
g_clear_object(&ddl->d3d11_proxy);
|
|
g_clear_object(&ddl->d3d11_proxy);
|
|
g_clear_pointer(&ddl->peer_process, CloseHandle);
|
|
g_clear_pointer(&ddl->peer_process, CloseHandle);
|
|
-#ifdef CONFIG_OPENGL
|
|
|
|
|
|
+#ifdef CONFIG_PIXMAN
|
|
pixman_region32_fini(&ddl->gl_damage);
|
|
pixman_region32_fini(&ddl->gl_damage);
|
|
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_OPENGL
|
|
egl_fb_destroy(&ddl->fb);
|
|
egl_fb_destroy(&ddl->fb);
|
|
#endif
|
|
#endif
|
|
#endif
|
|
#endif
|
|
@@ -787,7 +823,7 @@ dbus_display_listener_class_init(DBusDisplayListenerClass *klass)
|
|
static void
|
|
static void
|
|
dbus_display_listener_init(DBusDisplayListener *ddl)
|
|
dbus_display_listener_init(DBusDisplayListener *ddl)
|
|
{
|
|
{
|
|
-#ifdef CONFIG_OPENGL
|
|
|
|
|
|
+#ifdef CONFIG_PIXMAN
|
|
pixman_region32_init(&ddl->gl_damage);
|
|
pixman_region32_init(&ddl->gl_damage);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|