[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