gstgldisplay: Add public foreign_display property
authorDylan McCall <dylan@endlessm.com>
Wed, 26 Jun 2019 02:15:29 +0000 (19:15 -0700)
committerSebastian Dröge <slomo@coaxion.net>
Mon, 8 Jul 2019 20:46:58 +0000 (20:46 +0000)
We use this property in gst_gl_display_egl_from_gl_display, to set
foreign_display for the new GstGLDisplayEGL instance. This fixes a
problem where gst_gl_display_egl_finalize calls EglTerminate on a
pre-existing EGL connection.

gst-libs/gst/gl/egl/gstgldisplay_egl.c
gst-libs/gst/gl/gstgldisplay.c
gst-libs/gst/gl/gstgldisplay.h
gst-libs/gst/gl/wayland/gstgldisplay_wayland.c
gst-libs/gst/gl/x11/gstgldisplay_x11.c

index 8eb53a2..89aaca3 100644 (file)
@@ -64,12 +64,15 @@ G_DEFINE_TYPE (GstGLDisplayEGL, gst_gl_display_egl, GST_TYPE_GL_DISPLAY);
 
 static void gst_gl_display_egl_finalize (GObject * object);
 static guintptr gst_gl_display_egl_get_handle (GstGLDisplay * display);
+static gboolean gst_gl_display_egl_get_foreign_display (GstGLDisplay * display);
 
 static void
 gst_gl_display_egl_class_init (GstGLDisplayEGLClass * klass)
 {
   GST_GL_DISPLAY_CLASS (klass)->get_handle =
       GST_DEBUG_FUNCPTR (gst_gl_display_egl_get_handle);
+  GST_GL_DISPLAY_CLASS (klass)->get_foreign_display =
+      GST_DEBUG_FUNCPTR (gst_gl_display_egl_get_foreign_display);
 
   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_egl_finalize;
 }
@@ -264,6 +267,7 @@ gst_gl_display_egl_from_gl_display (GstGLDisplay * display)
   GstGLDisplayEGL *ret;
   GstGLDisplayType display_type;
   guintptr native_display;
+  gboolean foreign_display;
 
   g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
 
@@ -289,6 +293,7 @@ gst_gl_display_egl_from_gl_display (GstGLDisplay * display)
 
   display_type = gst_gl_display_get_handle_type (display);
   native_display = gst_gl_display_get_handle (display);
+  foreign_display = gst_gl_display_get_foreign_display (display);
 
   g_return_val_if_fail (native_display != 0, NULL);
   g_return_val_if_fail (display_type != GST_GL_DISPLAY_TYPE_NONE, NULL);
@@ -298,12 +303,14 @@ gst_gl_display_egl_from_gl_display (GstGLDisplay * display)
 
   ret->display =
       gst_gl_display_egl_get_from_native (display_type, native_display);
+  ret->foreign_display = foreign_display;
 
   if (!ret->display) {
     GST_WARNING_OBJECT (ret, "failed to get EGLDisplay from native display");
     gst_object_unref (ret);
     return NULL;
   }
+
   g_object_set_data_full (G_OBJECT (display), GST_GL_DISPLAY_EGL_NAME,
       gst_object_ref (ret), (GDestroyNotify) gst_object_unref);
 
@@ -315,3 +322,9 @@ gst_gl_display_egl_get_handle (GstGLDisplay * display)
 {
   return (guintptr) GST_GL_DISPLAY_EGL (display)->display;
 }
+
+static gboolean
+gst_gl_display_egl_get_foreign_display (GstGLDisplay * display)
+{
+  return GST_GL_DISPLAY_EGL (display)->foreign_display;
+}
index 3b72a56..0ec387f 100644 (file)
@@ -94,6 +94,8 @@ static guint gst_gl_display_signals[LAST_SIGNAL] = { 0 };
 static void gst_gl_display_dispose (GObject * object);
 static void gst_gl_display_finalize (GObject * object);
 static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);
+static gboolean gst_gl_display_default_get_foreign_display (GstGLDisplay *
+    display);
 static GstGLWindow *gst_gl_display_default_create_window (GstGLDisplay *
     display);
 
@@ -173,6 +175,7 @@ gst_gl_display_class_init (GstGLDisplayClass * klass)
       GST_TYPE_GL_CONTEXT, 1, GST_TYPE_GL_CONTEXT);
 
   klass->get_handle = gst_gl_display_default_get_handle;
+  klass->get_foreign_display = gst_gl_display_default_get_foreign_display;
   klass->create_window = gst_gl_display_default_create_window;
 
   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
@@ -361,6 +364,32 @@ gst_gl_display_default_get_handle (GstGLDisplay * display)
 }
 
 /**
+ * gst_gl_display_get_foreign_display:
+ * @context: a #GstGLDisplay
+ *
+ * Returns: whether the context belongs to a foreign display
+ *
+ * Since: 1.18
+ */
+gboolean
+gst_gl_display_get_foreign_display (GstGLDisplay * display)
+{
+  GstGLDisplayClass *klass;
+
+  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), FALSE);
+  klass = GST_GL_DISPLAY_GET_CLASS (display);
+  g_return_val_if_fail (klass->get_foreign_display != NULL, 0);
+
+  return klass->get_foreign_display (display);
+}
+
+static gboolean
+gst_gl_display_default_get_foreign_display (GstGLDisplay * display)
+{
+  return FALSE;
+}
+
+/**
  * gst_gl_display_filter_gl_api:
  * @display: a #GstGLDisplay
  * @gl_api: a #GstGLAPI to filter with
index 0e439c5..fec528b 100644 (file)
@@ -93,11 +93,12 @@ struct _GstGLDisplayClass
 {
   GstObjectClass object_class;
 
-  guintptr          (*get_handle)      (GstGLDisplay * display);
-  GstGLWindow *     (*create_window)    (GstGLDisplay * display);
+  guintptr          (*get_handle)           (GstGLDisplay * display);
+  GstGLWindow *     (*create_window)        (GstGLDisplay * display);
+  gboolean          (*get_foreign_display)  (GstGLDisplay * display);
 
   /*< private >*/
-  gpointer _padding[GST_PADDING];
+  gpointer _padding[GST_PADDING-1];
 };
 
 GST_GL_API
@@ -111,6 +112,8 @@ guintptr         gst_gl_display_get_handle             (GstGLDisplay * display);
 GST_GL_API
 GstGLDisplayType gst_gl_display_get_handle_type        (GstGLDisplay * display);
 GST_GL_API
+gboolean         gst_gl_display_get_foreign_display    (GstGLDisplay * display);
+GST_GL_API
 void             gst_gl_display_filter_gl_api          (GstGLDisplay * display,
                                                         GstGLAPI gl_api);
 GST_GL_API
index 6e0eb2c..a422b23 100644 (file)
@@ -50,6 +50,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (GstGLDisplayWayland, gst_gl_display_wayland,
 
 static void gst_gl_display_wayland_finalize (GObject * object);
 static guintptr gst_gl_display_wayland_get_handle (GstGLDisplay * display);
+static gboolean gst_gl_display_wayland_get_foreign_display (GstGLDisplay *
+    display);
 
 static void
 handle_xdg_wm_base_ping (void *user_data, struct xdg_wm_base *xdg_wm_base,
@@ -109,6 +111,8 @@ gst_gl_display_wayland_class_init (GstGLDisplayWaylandClass * klass)
 {
   GST_GL_DISPLAY_CLASS (klass)->get_handle =
       GST_DEBUG_FUNCPTR (gst_gl_display_wayland_get_handle);
+  GST_GL_DISPLAY_CLASS (klass)->get_foreign_display =
+      GST_DEBUG_FUNCPTR (gst_gl_display_wayland_get_foreign_display);
 
   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_wayland_finalize;
 }
@@ -214,6 +218,12 @@ gst_gl_display_wayland_get_handle (GstGLDisplay * display)
   return (guintptr) GST_GL_DISPLAY_WAYLAND (display)->display;
 }
 
+static gboolean
+gst_gl_display_wayland_get_foreign_display (GstGLDisplay * display)
+{
+  return GST_GL_DISPLAY_WAYLAND (display)->foreign_display;
+}
+
 struct xdg_wm_base *
 gst_gl_display_wayland_get_xdg_wm_base (GstGLDisplayWayland * display)
 {
index add4cad..a02e861 100644 (file)
@@ -44,6 +44,7 @@ G_DEFINE_TYPE (GstGLDisplayX11, gst_gl_display_x11, GST_TYPE_GL_DISPLAY);
 
 static void gst_gl_display_x11_finalize (GObject * object);
 static guintptr gst_gl_display_x11_get_handle (GstGLDisplay * display);
+static gboolean gst_gl_display_x11_get_foreign_display (GstGLDisplay * display);
 
 G_GNUC_INTERNAL
     gboolean gst_gl_display_x11_handle_event (GstGLDisplayX11 * display_x11);
@@ -56,6 +57,8 @@ gst_gl_display_x11_class_init (GstGLDisplayX11Class * klass)
 {
   GST_GL_DISPLAY_CLASS (klass)->get_handle =
       GST_DEBUG_FUNCPTR (gst_gl_display_x11_get_handle);
+  GST_GL_DISPLAY_CLASS (klass)->get_foreign_display =
+      GST_DEBUG_FUNCPTR (gst_gl_display_x11_get_foreign_display);
 
   G_OBJECT_CLASS (klass)->finalize = gst_gl_display_x11_finalize;
 }
@@ -168,6 +171,12 @@ gst_gl_display_x11_get_handle (GstGLDisplay * display)
   return (guintptr) GST_GL_DISPLAY_X11 (display)->display;
 }
 
+static gboolean
+gst_gl_display_x11_get_foreign_display (GstGLDisplay * display)
+{
+  return GST_GL_DISPLAY_X11 (display)->foreign_display;
+}
+
 static int
 _compare_xcb_window (GstGLWindowX11 * window_x11, xcb_window_t * window_id)
 {