On Mon, Mar 14, 2016 at 11:31 AM, Marc-André Lureau <marcandre.lureau@xxxxxxxxx> wrote: > On Mon, Mar 14, 2016 at 9:22 AM, Fabiano Fidêncio <fidencio@xxxxxxxxxx> wrote: >> 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. > > call_draw_done? ACK! > >> >>> 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 ? >> > > ok > >>> + } >>> + >>> + 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 > > > > -- > Marc-André Lureau _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel