summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/spice-widget-egl.c9
-rw-r--r--src/spice-widget-priv.h1
-rw-r--r--src/spice-widget.c79
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..0d1c3ae 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 call_draw_done;
SpiceGlScanout scanout;
} egl;
};
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 286eeca..891f2c8 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.call_draw_done) {
+ spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display));
+ d->egl.call_draw_done = 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.call_draw_done = 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)