On Fri, Mar 11, 2016 at 9:50 PM, Marc-André Lureau <marcandre.lureau@xxxxxxxxx> wrote: > GtkGLArea is the proper modern way to have opengl in an gtk+ > application. Unfortunately, it may use various backends and interfaces > to initialize it, but dmabuf image sharing requires egl atm. > > This patch keeps using our egl setup on X11, while it uses gtkglarea on > known gdk backend based on egl, such as the wayland one. This brings > wayland support for local gl to spice-gtk. > > Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > --- > src/spice-widget-egl.c | 9 ++++++ > src/spice-widget-priv.h | 1 + > src/spice-widget.c | 79 ++++++++++++++++++++++++++++++++++++++++++++----- > 3 files changed, 81 insertions(+), 8 deletions(-) > > diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c > index 1748189..1b3cd07 100644 > --- a/src/spice-widget-egl.c > +++ b/src/spice-widget-egl.c > @@ -29,6 +29,7 @@ > #include <libdrm/drm_fourcc.h> > > #include <gdk/gdkx.h> > +#include <gdk/gdkwayland.h> > > #define VERTS_ARRAY_SIZE (sizeof(GLfloat) * 4 * 4) > #define TEX_ARRAY_SIZE (sizeof(GLfloat) * 4 * 2) > @@ -200,6 +201,14 @@ gboolean spice_egl_init(SpiceDisplay *display, GError **err) > EGLNativeDisplayType dpy = 0; > GdkDisplay *gdk_dpy = gdk_display_get_default(); > > +#ifdef GDK_WINDOWING_WAYLAND > + if (GDK_IS_WAYLAND_DISPLAY(gdk_dpy)) { > + d->egl.ctx = eglGetCurrentContext(); > + dpy = (EGLNativeDisplayType)gdk_wayland_display_get_wl_display(gdk_dpy); > + d->egl.display = eglGetDisplay(dpy); > + return spice_egl_init_shaders(display, err); > + } > +#endif > #ifdef GDK_WINDOWING_X11 > if (GDK_IS_X11_DISPLAY(gdk_dpy)) { > dpy = (EGLNativeDisplayType)gdk_x11_display_get_xdisplay(gdk_dpy); > diff --git a/src/spice-widget-priv.h b/src/spice-widget-priv.h > index cf055d3..a60e72c 100644 > --- a/src/spice-widget-priv.h > +++ b/src/spice-widget-priv.h > @@ -137,6 +137,7 @@ struct _SpiceDisplayPrivate { > guint tex_pointer_id; > guint prog; > EGLImageKHR image; > + gboolean ack; Not sure if ack is the best name here. > SpiceGlScanout scanout; > } egl; > }; > diff --git a/src/spice-widget.c b/src/spice-widget.c > index 286eeca..9399e86 100644 > --- a/src/spice-widget.c > +++ b/src/spice-widget.c > @@ -539,12 +539,48 @@ static void grab_notify(SpiceDisplay *display, gboolean was_grabbed) > release_keys(display); > } > > +static gboolean > +gl_area_render(GtkGLArea *area, GdkGLContext *context, gpointer user_data) > +{ > + SpiceDisplay *display = SPICE_DISPLAY(user_data); > + SpiceDisplayPrivate *d = display->priv; > + > + spice_egl_update_display(display); > + glFlush(); > + if (d->egl.ack) { > + spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display)); > + d->egl.ack = false; s/false/FALSE ? > + } > + > + return TRUE; > +} > + > +static void > +gl_area_realize(GtkGLArea *area, gpointer user_data) > +{ > + SpiceDisplay *display = SPICE_DISPLAY(user_data); > + GError *err = NULL; > + > + gtk_gl_area_make_current(area); > + if (gtk_gl_area_get_error(area) != NULL) > + return; > + > + if (!spice_egl_init(display, &err)) { > + g_critical("egl init failed: %s", err->message); > + g_clear_error(&err); > + } > +} > + > static void > drawing_area_realize(GtkWidget *area, gpointer user_data) > { > +#ifdef GDK_WINDOWING_X11 > SpiceDisplay *display = SPICE_DISPLAY(user_data); > GError *err = NULL; > > + if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) > + return; > + > if (!spice_egl_init(display, &err)) { > g_critical("egl init failed: %s", err->message); > g_clear_error(&err); > @@ -554,6 +590,7 @@ drawing_area_realize(GtkWidget *area, gpointer user_data) > g_critical("egl realize failed: %s", err->message); > g_clear_error(&err); > } > +#endif > } > > static void spice_display_init(SpiceDisplay *display) > @@ -574,6 +611,16 @@ static void spice_display_init(SpiceDisplay *display) > gtk_widget_set_double_buffered(area, true); > gtk_stack_set_visible_child(GTK_STACK(widget), area); > > + area = gtk_gl_area_new(); > + gtk_gl_area_set_required_version(GTK_GL_AREA(area), 3, 2); > + gtk_gl_area_set_auto_render(GTK_GL_AREA(area), false); > + g_object_connect(area, > + "signal::render", gl_area_render, display, > + "signal::realize", gl_area_realize, display, > + NULL); > + gtk_stack_add_named(GTK_STACK(widget), area, "gl-area"); > + gtk_widget_show_all(widget); > + > g_signal_connect(display, "grab-broken-event", G_CALLBACK(grab_broken), NULL); > g_signal_connect(display, "grab-notify", G_CALLBACK(grab_notify), NULL); > > @@ -1152,11 +1199,20 @@ static void set_egl_enabled(SpiceDisplay *display, bool enabled) > if (d->egl.enabled == enabled) > return; > > - /* even though the function is marked as deprecated, it's the > - * only way I found to prevent glitches when the window is > - * resized. */ > - area = gtk_stack_get_child_by_name(GTK_STACK(display), "draw-area"); > - gtk_widget_set_double_buffered(GTK_WIDGET(area), !enabled); > +#ifdef GDK_WINDOWING_X11 > + if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) { > + /* even though the function is marked as deprecated, it's the > + * only way I found to prevent glitches when the window is > + * resized. */ > + area = gtk_stack_get_child_by_name(GTK_STACK(display), "draw-area"); > + gtk_widget_set_double_buffered(GTK_WIDGET(area), !enabled); > + } else > +#endif > + { > + area = gtk_stack_get_child_by_name(GTK_STACK(display), "gl-area"); > + gtk_stack_set_visible_child_name(GTK_STACK(display), > + enabled ? "gl-area" : "draw-area"); > + } > > if (enabled) { > spice_egl_resize_display(display, d->ww, d->wh); > @@ -1171,7 +1227,8 @@ static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data) > SpiceDisplayPrivate *d = display->priv; > g_return_val_if_fail(d != NULL, false); > > - if (d->egl.enabled) { > + if (d->egl.enabled && > + g_str_equal(gtk_stack_get_visible_child_name(GTK_STACK(display)), "draw-area")) { > spice_egl_update_display(display); > return false; > } > @@ -2437,12 +2494,18 @@ static void gl_draw(SpiceDisplay *display, > guint32 x, guint32 y, guint32 w, guint32 h) > { > SpiceDisplayPrivate *d = display->priv; > + GtkWidget *gl = gtk_stack_get_child_by_name(GTK_STACK(display), "gl-area"); > > SPICE_DEBUG("%s", __FUNCTION__); > set_egl_enabled(display, true); > > - spice_egl_update_display(display); > - spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display)); > + if (gtk_stack_get_visible_child(GTK_STACK(display)) == gl) { > + gtk_gl_area_queue_render(GTK_GL_AREA(gl)); > + d->egl.ack = true; s/true/TRUE ? > + } else { > + spice_egl_update_display(display); > + spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display)); > + } > } > > static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data) > -- > 2.5.0 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel