[Spice-commits] 3 commits - src/spice-widget-egl.c

Marc-André Lureau elmarco at kemper.freedesktop.org
Mon May 23 16:42:58 UTC 2016


 src/spice-widget-egl.c |   96 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 70 insertions(+), 26 deletions(-)

New commits:
commit 3539ac6212d506128bd38aad032e0363e78cb4f6
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Fri May 20 16:35:08 2016 +0200

    egl: set current context, fix multiple display
    
    On X11, each widget has its own context. Make sure we are using the
    widget associated context when using gl.
    
    With gtk 3.16, glEGLImageTargetTexture2DOES() can be called during
    update scanout, since we can call gtk_gl_area_make_current(). On < 3.16,
    do it before drawing.
    
    Fixes:
    https://bugzilla.redhat.com/show_bug.cgi?id=1337721
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 0054bc9..c60765c 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -284,12 +284,39 @@ end:
     return TRUE;
 }
 
+static gboolean
+gl_make_current(SpiceDisplay *display, GError **err)
+{
+    SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+    if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+        EGLBoolean success = eglMakeCurrent(d->egl.display,
+                                            d->egl.surface,
+                                            d->egl.surface,
+                                            d->egl.ctx);
+        if (success != EGL_TRUE) {
+            g_set_error_literal(err, SPICE_CLIENT_ERROR,
+                                SPICE_CLIENT_ERROR_FAILED,
+                                "failed to activate context");
+            return FALSE;
+        }
+    }
+#if GTK_CHECK_VERSION(3,16,0)
+    else {
+        GtkWidget *area = gtk_stack_get_child_by_name(d->stack, "gl-area");
+
+        gtk_gl_area_make_current(GTK_GL_AREA(area));
+    }
+#endif
+
+    return TRUE;
+}
+
 static gboolean spice_widget_init_egl_win(SpiceDisplay *display, GdkWindow *win,
                                           GError **err)
 {
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
     EGLNativeWindowType native = 0;
-    EGLBoolean b;
 
     if (d->egl.surface)
         return TRUE;
@@ -316,15 +343,8 @@ static gboolean spice_widget_init_egl_win(SpiceDisplay *display, GdkWindow *win,
         return FALSE;
     }
 
-    b = eglMakeCurrent(d->egl.display,
-                       d->egl.surface,
-                       d->egl.surface,
-                       d->egl.ctx);
-    if (!b) {
-        g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
-                            "failed to activate context");
+    if (!gl_make_current(display, err))
         return FALSE;
-    }
 
     return TRUE;
 }
@@ -349,6 +369,9 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
 
     SPICE_DEBUG("egl unrealize %p", d->egl.surface);
 
+    if (!gl_make_current(display, NULL))
+        return;
+
     if (d->egl.image != NULL) {
         eglDestroyImageKHR(d->egl.display, d->egl.image);
         d->egl.image = NULL;
@@ -402,6 +425,9 @@ void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
     SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
     int prog;
 
+    if (!gl_make_current(display, NULL))
+        return;
+
     glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
 
     glUseProgram(d->egl.prog);
@@ -521,6 +547,8 @@ void spice_egl_update_display(SpiceDisplay *display)
     int prog;
 
     g_return_if_fail(d->ready);
+    if (!gl_make_current(display, NULL))
+        return;
 
     spice_display_get_scaling(display, &s, &x, &y, &w, &h);
 
@@ -553,8 +581,14 @@ void spice_egl_update_display(SpiceDisplay *display)
     }
     SPICE_DEBUG("update %f +%d+%d %dx%d +%f+%f %fx%f", s, x, y, w, h,
                 tx, ty, tw, th);
-
     glBindTexture(GL_TEXTURE_2D, d->egl.tex_id);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+#if !GTK_CHECK_VERSION(3,16,0)
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)d->egl.image);
+#endif
+
     glDisable(GL_BLEND);
     glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
     glUseProgram(d->egl.prog);
@@ -588,7 +622,6 @@ void spice_egl_update_display(SpiceDisplay *display)
     glUseProgram(prog);
 }
 
-
 G_GNUC_INTERNAL
 gboolean spice_egl_update_scanout(SpiceDisplay *display,
                                   const SpiceGlScanout *scanout,
@@ -633,11 +666,14 @@ gboolean spice_egl_update_scanout(SpiceDisplay *display,
                                        (EGLClientBuffer)NULL,
                                        attrs);
 
-    glBindTexture(GL_TEXTURE_2D, d->egl.tex_id);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)d->egl.image);
     d->egl.scanout = *scanout;
 
+#if GTK_CHECK_VERSION(3,16,0)
+    if (!gl_make_current(display, NULL))
+        return FALSE;
+
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)d->egl.image);
+#endif
+
     return TRUE;
 }
commit 8873ff3de67671a72468b0da3e5285dcc070af5c
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Fri May 20 17:07:15 2016 +0200

    egl: don't terminate display
    
    This is global to the display connection: all egl resources will be
    released, including those from other widgets or from the application.
    
    Fix spice/virgl display being rendered black after another widget
    display is destroyed.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index a3db856..0054bc9 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -390,7 +390,9 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
 
         eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
                        EGL_NO_CONTEXT);
-        eglTerminate(d->egl.display);
+
+        /* do not call eglterminate() since egl may be used by
+         * somebody else code */
     }
 }
 
commit cb9252441471a4f0f877f58f754c55e2cececc55
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Fri May 20 15:36:09 2016 +0200

    egl: don't destroy wayland egl context
    
    The egl context is from Gtk on Wayland. Destroy it only on X11.
    
    Signed-off-by: Marc-André Lureau <marcandre.lureau at gmail.com>
    Acked-by: Pavel Grunt <pgrunt at redhat.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 961dcfa..a3db856 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -364,10 +364,6 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
         d->egl.tex_pointer_id = 0;
     }
 
-    if (d->egl.surface != EGL_NO_SURFACE) {
-        eglDestroySurface(d->egl.display, d->egl.surface);
-        d->egl.surface = EGL_NO_SURFACE;
-    }
     if (d->egl.vbuf_id) {
         glDeleteBuffers(1, &d->egl.vbuf_id);
         d->egl.vbuf_id = 0;
@@ -378,14 +374,24 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
         d->egl.prog = 0;
     }
 
-    if (d->egl.ctx) {
-        eglDestroyContext(d->egl.display, d->egl.ctx);
-        d->egl.ctx = 0;
+    if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+        /* egl.surface && egl.ctx are only created on x11, see
+           spice_egl_init() */
+
+        if (d->egl.surface != EGL_NO_SURFACE) {
+            eglDestroySurface(d->egl.display, d->egl.surface);
+            d->egl.surface = EGL_NO_SURFACE;
+        }
+
+        if (d->egl.ctx) {
+            eglDestroyContext(d->egl.display, d->egl.ctx);
+            d->egl.ctx = 0;
+        }
+
+        eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                       EGL_NO_CONTEXT);
+        eglTerminate(d->egl.display);
     }
-
-    eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                   EGL_NO_CONTEXT);
-    eglTerminate(d->egl.display);
 }
 
 G_GNUC_INTERNAL


More information about the Spice-commits mailing list