[Spice-commits] 4 commits - src/spice-widget.c src/spice-widget-cairo.c src/spice-widget-priv.h
Marc-André Lureau
elmarco at kemper.freedesktop.org
Wed May 25 10:42:36 UTC 2016
src/spice-widget-cairo.c | 46 +++++++++---------
src/spice-widget-priv.h | 25 ++++------
src/spice-widget.c | 116 +++++++++++++++++++++++------------------------
3 files changed, 95 insertions(+), 92 deletions(-)
New commits:
commit 69383107ea337a50d2c032f8f2c78ed99a4f06d6
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date: Tue May 24 21:23:20 2016 +0200
egl: fix delayed widget realize
When the display is not yet realized, spice_display_widget_gl_scanout()
will fail because the egl context is not ready. The display is never
marked ready because the egl.image (and egl.scanout) is not set, and
some clients, such as virt-viewer will not realize the widget until the
display is ready.
Deal with gl scanout updates when the widget is not yet realized, and
mark the display as ready when egl is enabled (when last display draw
signal is from gl).
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
Acked-by: Pavel Grunt <pgrunt at redhat.com>
diff --git a/src/spice-widget.c b/src/spice-widget.c
index f13a066..9a4b204 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -238,7 +238,7 @@ static void update_ready(SpiceDisplay *display)
if (d->monitor_ready) {
#ifndef G_OS_WIN32
- ready = d->egl.enabled ? d->egl.image != NULL : d->mark != 0;
+ ready = d->egl.enabled || d->mark != 0;
#else
ready = d->mark != 0;
#endif
@@ -2296,9 +2296,12 @@ static void update_area(SpiceDisplay *display,
#ifndef G_OS_WIN32
if (d->egl.enabled) {
+ const SpiceGlScanout *so =
+ spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display));
+ g_return_if_fail(so != NULL);
primary = (GdkRectangle) {
- .width = d->egl.scanout.width,
- .height = d->egl.scanout.height
+ .width = so->width,
+ .height = so->height
};
} else
#endif
@@ -2611,21 +2614,22 @@ G_GNUC_INTERNAL
void spice_display_widget_gl_scanout(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
- const SpiceGlScanout *scanout;
- GError *err = NULL;
SPICE_DEBUG("%s: got scanout", __FUNCTION__);
set_egl_enabled(display, true);
- g_return_if_fail(d->egl.context_ready);
+ if (d->egl.context_ready) {
+ const SpiceGlScanout *scanout;
+ GError *err = NULL;
- scanout = spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display));
- /* should only be called when the display has a scanout */
- g_return_if_fail(scanout != NULL);
+ scanout = spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display));
+ /* should only be called when the display has a scanout */
+ g_return_if_fail(scanout != NULL);
- if (!spice_egl_update_scanout(display, scanout, &err)) {
- g_critical("update scanout failed: %s", err->message);
- g_clear_error(&err);
+ if (!spice_egl_update_scanout(display, scanout, &err)) {
+ g_critical("update scanout failed: %s", err->message);
+ g_clear_error(&err);
+ }
}
}
commit 4e08108d0a78458246e82a7c7af9107b8fa49df9
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date: Wed May 25 12:05:36 2016 +0200
gtk: remove unneeded check
spice_cairo_draw_event() can deal with d->canvas.surface == NULL.
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
Acked-by: Pavel Grunt <pgrunt at redhat.com>
diff --git a/src/spice-widget.c b/src/spice-widget.c
index a37faad..f13a066 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1227,7 +1227,6 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
if (d->mark == 0 || d->canvas.data == NULL ||
d->area.width == 0 || d->area.height == 0)
return false;
- g_return_val_if_fail(d->canvas.surface != NULL, false);
spice_cairo_draw_event(display, cr);
update_mouse_pointer(display);
commit 28c41f23b43a1d79d2a88447bae1273ded15e013
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date: Tue May 24 20:45:52 2016 +0200
gtk: rename spicex_* functions
spice-gtk used to have x11/shm backend, now it's only cairo
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
Acked-by: Pavel Grunt <pgrunt at redhat.com>
diff --git a/src/spice-widget-cairo.c b/src/spice-widget-cairo.c
index bd7ce6a..0e84649 100644
--- a/src/spice-widget-cairo.c
+++ b/src/spice-widget-cairo.c
@@ -23,7 +23,7 @@
G_GNUC_INTERNAL
-int spicex_image_create(SpiceDisplay *display)
+int spice_cairo_image_create(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
@@ -51,7 +51,7 @@ int spicex_image_create(SpiceDisplay *display)
}
G_GNUC_INTERNAL
-void spicex_image_destroy(SpiceDisplay *display)
+void spice_cairo_image_destroy(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
@@ -62,7 +62,7 @@ void spicex_image_destroy(SpiceDisplay *display)
}
G_GNUC_INTERNAL
-void spicex_draw_event(SpiceDisplay *display, cairo_t *cr)
+void spice_cairo_draw_event(SpiceDisplay *display, cairo_t *cr)
{
SpiceDisplayPrivate *d = display->priv;
cairo_rectangle_int_t rect;
@@ -130,7 +130,7 @@ void spicex_draw_event(SpiceDisplay *display, cairo_t *cr)
}
G_GNUC_INTERNAL
-gboolean spicex_is_scaled(SpiceDisplay *display)
+gboolean spice_cairo_is_scaled(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
return d->allow_scaling;
diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 266cc87..e36baf3 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -147,10 +147,10 @@ struct _SpiceDisplayPrivate {
#endif
};
-int spicex_image_create (SpiceDisplay *display);
-void spicex_image_destroy (SpiceDisplay *display);
-void spicex_draw_event (SpiceDisplay *display, cairo_t *cr);
-gboolean spicex_is_scaled (SpiceDisplay *display);
+int spice_cairo_image_create (SpiceDisplay *display);
+void spice_cairo_image_destroy (SpiceDisplay *display);
+void spice_cairo_draw_event (SpiceDisplay *display, cairo_t *cr);
+gboolean spice_cairo_is_scaled (SpiceDisplay *display);
void spice_display_get_scaling (SpiceDisplay *display, double *s, int *x, int *y, int *w, int *h);
gboolean spice_egl_init (SpiceDisplay *display, GError **err);
gboolean spice_egl_realize_display (SpiceDisplay *display, GdkWindow *win,
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 2272a26..a37faad 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -417,7 +417,7 @@ static void spice_display_dispose(GObject *obj)
SPICE_DEBUG("spice display dispose");
- spicex_image_destroy(display);
+ spice_cairo_image_destroy(display);
g_clear_object(&d->session);
d->gtk_session = NULL;
@@ -1113,7 +1113,7 @@ static void recalc_geometry(GtkWidget *widget)
SpiceDisplayPrivate *d = display->priv;
gdouble zoom = 1.0;
- if (spicex_is_scaled(display))
+ if (spice_cairo_is_scaled(display))
zoom = (gdouble)d->zoom_level / 100;
SPICE_DEBUG("recalc geom monitor: %d:%d, guest +%d+%d:%dx%d, window %dx%d, zoom %g",
@@ -1229,7 +1229,7 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
return false;
g_return_val_if_fail(d->canvas.surface != NULL, false);
- spicex_draw_event(display, cr);
+ spice_cairo_draw_event(display, cr);
update_mouse_pointer(display);
return true;
@@ -1743,10 +1743,9 @@ static int button_mask_gdk_to_spice(int gdk)
return spice;
}
-G_GNUC_INTERNAL
-void spicex_transform_input (SpiceDisplay *display,
- double window_x, double window_y,
- int *input_x, int *input_y)
+static void transform_input(SpiceDisplay *display,
+ double window_x, double window_y,
+ int *input_x, int *input_y)
{
SpiceDisplayPrivate *d = display->priv;
int display_x, display_y, display_w, display_h;
@@ -1799,7 +1798,7 @@ static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
try_keyboard_grab(display);
}
- spicex_transform_input (display, motion->x, motion->y, &x, &y);
+ transform_input(display, motion->x, motion->y, &x, &y);
switch (d->mouse_mode) {
case SPICE_MOUSE_MODE_CLIENT:
@@ -1872,7 +1871,7 @@ static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
if (d->disable_inputs)
return true;
- spicex_transform_input (display, button->x, button->y, &x, &y);
+ transform_input(display, button->x, button->y, &x, &y);
if ((x < 0 || x >= d->area.width ||
y < 0 || y >= d->area.height) &&
d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {
@@ -1956,7 +1955,7 @@ static void update_image(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
- spicex_image_create(display);
+ spice_cairo_image_create(display);
if (d->canvas.convert)
do_color_convert(display, &d->area);
}
@@ -1977,7 +1976,7 @@ static void realize(GtkWidget *widget)
static void unrealize(GtkWidget *widget)
{
- spicex_image_destroy(SPICE_DISPLAY(widget));
+ spice_cairo_image_destroy(SPICE_DISPLAY(widget));
#ifndef G_OS_WIN32
spice_egl_unrealize_display(SPICE_DISPLAY(widget));
#endif
@@ -2323,7 +2322,7 @@ static void update_area(SpiceDisplay *display,
if (!d->egl.enabled)
#endif
{
- spicex_image_destroy(display);
+ spice_cairo_image_destroy(display);
if (gtk_widget_get_realized(GTK_WIDGET(display)))
update_image(display);
}
@@ -2354,7 +2353,7 @@ static void primary_destroy(SpiceChannel *channel, gpointer data)
SpiceDisplay *display = SPICE_DISPLAY(data);
SpiceDisplayPrivate *d = display->priv;
- spicex_image_destroy(display);
+ spice_cairo_image_destroy(display);
d->canvas.width = 0;
d->canvas.height = 0;
d->canvas.stride = 0;
@@ -2512,7 +2511,7 @@ void spice_display_get_scaling(SpiceDisplay *display,
wh = fbh;
}
- if (!spicex_is_scaled(display)) {
+ if (!spice_cairo_is_scaled(display)) {
s = 1.0;
x = 0;
y = 0;
commit 45506fadb3e5db53289de9b1a594a4200f509d36
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date: Mon Feb 29 17:53:31 2016 +0100
gtk: move canvas related data in its own structure
Group canvas related data to a sub-structure.
Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
Acked-by: Pavel Grunt <pgrunt at redhat.com>
diff --git a/src/spice-widget-cairo.c b/src/spice-widget-cairo.c
index 5d93a9f..bd7ce6a 100644
--- a/src/spice-widget-cairo.c
+++ b/src/spice-widget-cairo.c
@@ -27,22 +27,24 @@ int spicex_image_create(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
- if (d->ximage != NULL)
+ if (d->canvas.surface != NULL)
return 0;
- if (d->format == SPICE_SURFACE_FMT_16_555 ||
- d->format == SPICE_SURFACE_FMT_16_565) {
- d->convert = TRUE;
- d->data = g_malloc0(d->area.width * d->area.height * 4);
+ if (d->canvas.format == SPICE_SURFACE_FMT_16_555 ||
+ d->canvas.format == SPICE_SURFACE_FMT_16_565) {
+ d->canvas.convert = TRUE;
+ d->canvas.data = g_malloc0(d->area.width * d->area.height * 4);
- d->ximage = cairo_image_surface_create_for_data
- (d->data, CAIRO_FORMAT_RGB24, d->area.width, d->area.height, d->area.width * 4);
+ d->canvas.surface = cairo_image_surface_create_for_data
+ (d->canvas.data, CAIRO_FORMAT_RGB24,
+ d->area.width, d->area.height, d->area.width * 4);
} else {
- d->convert = FALSE;
+ d->canvas.convert = FALSE;
- d->ximage = cairo_image_surface_create_for_data
- (d->data, CAIRO_FORMAT_RGB24, d->width, d->height, d->stride);
+ d->canvas.surface = cairo_image_surface_create_for_data
+ (d->canvas.data, CAIRO_FORMAT_RGB24,
+ d->canvas.width, d->canvas.height, d->canvas.stride);
}
return 0;
@@ -53,10 +55,10 @@ void spicex_image_destroy(SpiceDisplay *display)
{
SpiceDisplayPrivate *d = display->priv;
- g_clear_pointer(&d->ximage, cairo_surface_destroy);
- if (d->convert)
- g_clear_pointer(&d->data, g_free);
- d->convert = FALSE;
+ g_clear_pointer(&d->canvas.surface, cairo_surface_destroy);
+ if (d->canvas.convert)
+ g_clear_pointer(&d->canvas.data, g_free);
+ d->canvas.convert = FALSE;
}
G_GNUC_INTERNAL
@@ -85,7 +87,7 @@ void spicex_draw_event(SpiceDisplay *display, cairo_t *cr)
/* Optionally cut out the inner area where the pixmap
will be drawn. This avoids 'flashing' since we're
not double-buffering. */
- if (d->ximage) {
+ if (d->canvas.surface) {
rect.x = x;
rect.y = y;
rect.width = w;
@@ -103,13 +105,13 @@ void spicex_draw_event(SpiceDisplay *display, cairo_t *cr)
cairo_fill(cr);
/* Draw the display */
- if (d->ximage) {
+ if (d->canvas.surface) {
cairo_translate(cr, x, y);
cairo_rectangle(cr, 0, 0, w, h);
cairo_scale(cr, s, s);
- if (!d->convert)
+ if (!d->canvas.convert)
cairo_translate(cr, -d->area.x, -d->area.y);
- cairo_set_source_surface(cr, d->ximage, 0, 0);
+ cairo_set_source_surface(cr, d->canvas.surface, 0, 0);
cairo_fill(cr);
if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER &&
diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h
index 50d5ea1..266cc87 100644
--- a/src/spice-widget-priv.h
+++ b/src/spice-widget-priv.h
@@ -66,23 +66,22 @@ struct _SpiceDisplayPrivate {
/* state */
gboolean ready;
gboolean monitor_ready;
- enum SpiceSurfaceFmt format;
- gint width, height, stride;
- gpointer data_origin; /* the original display image data */
- gpointer data; /* converted if necessary to 32 bits */
-
+ struct {
+ enum SpiceSurfaceFmt format;
+ gint width, height, stride;
+ gpointer data_origin; /* the original display image data */
+ gpointer data; /* converted if necessary to 32 bits */
+ bool convert;
+ cairo_surface_t *surface;
+ } canvas;
GdkRectangle area;
/* window border */
gint ww, wh, mx, my;
- bool convert;
gboolean allow_scaling;
gboolean only_downscale;
gboolean disable_inputs;
- /* TODO: make a display object instead? */
- cairo_surface_t *ximage;
-
SpiceSession *session;
SpiceGtkSession *gtk_session;
SpiceMainChannel *main;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index e337321..2272a26 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -178,7 +178,7 @@ static void scaling_updated(SpiceDisplay *display)
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display));
recalc_geometry(GTK_WIDGET(display));
- if (d->ximage && window) { /* if not yet shown */
+ if (d->canvas.surface && window) { /* if not yet shown */
gtk_widget_queue_draw(GTK_WIDGET(display));
}
update_size_request(display);
@@ -320,7 +320,7 @@ void spice_display_widget_update_monitor_area(SpiceDisplay *display)
whole:
g_clear_pointer(&monitors, g_array_unref);
/* by display whole surface */
- update_area(display, 0, 0, d->width, d->height);
+ update_area(display, 0, 0, d->canvas.width, d->canvas.height);
set_monitor_ready(display, true);
}
@@ -1144,34 +1144,34 @@ static void recalc_geometry(GtkWidget *widget)
static gboolean do_color_convert(SpiceDisplay *display, GdkRectangle *r)
{
SpiceDisplayPrivate *d = display->priv;
- guint32 *dest = d->data;
- guint16 *src = d->data_origin;
+ guint32 *dest = d->canvas.data;
+ guint16 *src = d->canvas.data_origin;
gint x, y;
g_return_val_if_fail(r != NULL, false);
- g_return_val_if_fail(d->format == SPICE_SURFACE_FMT_16_555 ||
- d->format == SPICE_SURFACE_FMT_16_565, false);
+ g_return_val_if_fail(d->canvas.format == SPICE_SURFACE_FMT_16_555 ||
+ d->canvas.format == SPICE_SURFACE_FMT_16_565, false);
- src += (d->stride / 2) * r->y + r->x;
+ src += (d->canvas.stride / 2) * r->y + r->x;
dest += d->area.width * (r->y - d->area.y) + (r->x - d->area.x);
- if (d->format == SPICE_SURFACE_FMT_16_555) {
+ if (d->canvas.format == SPICE_SURFACE_FMT_16_555) {
for (y = 0; y < r->height; y++) {
for (x = 0; x < r->width; x++) {
dest[x] = CONVERT_0555_TO_0888(src[x]);
}
dest += d->area.width;
- src += d->stride / 2;
+ src += d->canvas.stride / 2;
}
- } else if (d->format == SPICE_SURFACE_FMT_16_565) {
+ } else if (d->canvas.format == SPICE_SURFACE_FMT_16_565) {
for (y = 0; y < r->height; y++) {
for (x = 0; x < r->width; x++) {
dest[x] = CONVERT_0565_TO_0888(src[x]);
}
dest += d->area.width;
- src += d->stride / 2;
+ src += d->canvas.stride / 2;
}
}
@@ -1224,10 +1224,10 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
}
#endif
- if (d->mark == 0 || d->data == NULL ||
+ if (d->mark == 0 || d->canvas.data == NULL ||
d->area.width == 0 || d->area.height == 0)
return false;
- g_return_val_if_fail(d->ximage != NULL, false);
+ g_return_val_if_fail(d->canvas.surface != NULL, false);
spicex_draw_event(display, cr);
update_mouse_pointer(display);
@@ -1957,7 +1957,7 @@ static void update_image(SpiceDisplay *display)
SpiceDisplayPrivate *d = display->priv;
spicex_image_create(display);
- if (d->convert)
+ if (d->canvas.convert)
do_color_convert(display, &d->area);
}
@@ -2306,8 +2306,8 @@ static void update_area(SpiceDisplay *display,
#endif
{
primary = (GdkRectangle) {
- .width = d->width,
- .height = d->height
+ .width = d->canvas.width,
+ .height = d->canvas.height
};
}
@@ -2340,11 +2340,11 @@ static void primary_create(SpiceChannel *channel, gint format,
SpiceDisplay *display = data;
SpiceDisplayPrivate *d = display->priv;
- d->format = format;
- d->stride = stride;
- d->width = width;
- d->height = height;
- d->data_origin = d->data = imgdata;
+ d->canvas.format = format;
+ d->canvas.stride = stride;
+ d->canvas.width = width;
+ d->canvas.height = height;
+ d->canvas.data_origin = d->canvas.data = imgdata;
spice_display_widget_update_monitor_area(display);
}
@@ -2355,11 +2355,11 @@ static void primary_destroy(SpiceChannel *channel, gpointer data)
SpiceDisplayPrivate *d = display->priv;
spicex_image_destroy(display);
- d->width = 0;
- d->height = 0;
- d->stride = 0;
- d->data = NULL;
- d->data_origin = NULL;
+ d->canvas.width = 0;
+ d->canvas.height = 0;
+ d->canvas.stride = 0;
+ d->canvas.data = NULL;
+ d->canvas.data_origin = NULL;
set_monitor_ready(display, false);
}
@@ -2403,7 +2403,7 @@ static void invalidate(SpiceChannel *channel,
if (!gdk_rectangle_intersect(&rect, &d->area, &rect))
return;
- if (d->convert)
+ if (d->canvas.convert)
do_color_convert(display, &rect);
spice_display_get_scaling(display, &s,
@@ -2874,12 +2874,12 @@ GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display)
int x, y;
/* TODO: ensure d->data has been exposed? */
- g_return_val_if_fail(d->data != NULL, NULL);
+ g_return_val_if_fail(d->canvas.data != NULL, NULL);
data = g_malloc0(d->area.width * d->area.height * 3);
- src = d->data;
+ src = d->canvas.data;
dest = data;
- src += d->area.y * d->stride + d->area.x * 4;
+ src += d->area.y * d->canvas.stride + d->area.x * 4;
for (y = 0; y < d->area.height; ++y) {
for (x = 0; x < d->area.width; ++x) {
dest[0] = src[x * 4 + 2];
@@ -2887,7 +2887,7 @@ GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display)
dest[2] = src[x * 4 + 0];
dest += 3;
}
- src += d->stride;
+ src += d->canvas.stride;
}
pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, false,
8, d->area.width, d->area.height,
More information about the Spice-commits
mailing list