eglglessink: Fix setup chain logic
authorReynaldo H. Verdejo Pinochet <reynaldo@collabora.com>
Fri, 14 Sep 2012 23:49:48 +0000 (20:49 -0300)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 18 Oct 2012 12:35:10 +0000 (14:35 +0200)
Mostly a procedural reordering. Idea is to avoid
trying to setup a surface without a display.This
change relies on the asumption that:

1.- set_window_handle() can happen at any time
2.- setcaps will never get called before _start()
    is done.

If both conditions are meet the new procedure
should work as expected.

ext/eglgles/gsteglglessink.c
ext/eglgles/gsteglglessink.h

index 27fc785..bdf7b41 100644 (file)
@@ -275,6 +275,7 @@ static GstFlowReturn gst_eglglessink_render_and_display (GstEglGlesSink * sink,
 static inline gboolean got_gl_error (const char *wtf);
 static inline void show_egl_error (const char *wtf);
 static void gst_eglglessink_wipe_fmt (gpointer data);
+static inline gboolean egl_init (GstEglGlesSink * eglglessink);
 
 static GstBufferClass *gsteglglessink_buffer_parent_class = NULL;
 #define GST_TYPE_EGLGLESBUFFER (gst_eglglesbuffer_get_type())
@@ -824,15 +825,10 @@ gst_eglglessink_fill_supported_fbuffer_configs (GstEglGlesSink * eglglessink)
   return ret;
 }
 
-gboolean
-gst_eglglessink_start (GstBaseSink * sink)
+static inline gboolean
+egl_init (GstEglGlesSink * eglglessink)
 {
-  gboolean ret;
-  GstEglGlesSink *eglglessink = GST_EGLGLESSINK (sink);
-
-  ret = platform_wrapper_init ();
-
-  if (!ret) {
+  if (!platform_wrapper_init ()) {
     GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL platform wrapper");
     goto HANDLE_ERROR;
   }
@@ -842,14 +838,43 @@ gst_eglglessink_start (GstBaseSink * sink)
     goto HANDLE_ERROR;
   }
 
+  gst_eglglessink_init_egl_exts (eglglessink);
+
   if (!gst_eglglessink_fill_supported_fbuffer_configs (eglglessink)) {
     GST_ERROR_OBJECT (eglglessink, "Display support NONE of our configs");
     goto HANDLE_ERROR;
   }
 
+  g_mutex_lock (eglglessink->flow_lock);
+  eglglessink->egl_started = TRUE;
+  g_mutex_unlock (eglglessink->flow_lock);
+
+  return TRUE;
+
+HANDLE_ERROR:
+  GST_ERROR_OBJECT (eglglessink, "Failed to perform EGL init");
+  return FALSE;
+}
+
+gboolean
+gst_eglglessink_start (GstBaseSink * sink)
+{
+  GstEglGlesSink *eglglessink = GST_EGLGLESSINK (sink);
+
+  if (!egl_init (eglglessink)) {
+    GST_ERROR_OBJECT (eglglessink, "EGL uninitialized. Bailing out");
+    goto HANDLE_ERROR;
+  }
+
   /* Ask for a window to render to */
   gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (eglglessink));
 
+  if (!eglglessink->have_window && !eglglessink->can_create_window) {
+    GST_ERROR_OBJECT (eglglessink, "Window handle unavailable and we "
+        "were instructed not to create an internal one. Bailing out.");
+    goto HANDLE_ERROR;
+  }
+
   return TRUE;
 
 HANDLE_ERROR:
@@ -1344,13 +1369,20 @@ gst_eglglessink_set_window_handle (GstXOverlay * overlay, guintptr id)
   eglglessink->have_window = TRUE;
   g_mutex_unlock (eglglessink->flow_lock);
 
+  if (!eglglessink->egl_started) {
+    GST_INFO_OBJECT (eglglessink, "Got a handle, doing EGL initialization");
+    if (!egl_init (eglglessink)) {
+      GST_ERROR_OBJECT (eglglessink, "EGL Initialization failed!");
+      goto HANDLE_ERROR;
+    }
+  }
+
+/*
   if (!gst_eglglessink_init_egl_surface (eglglessink)) {
     GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL surface!");
     goto HANDLE_ERROR;
   }
-
-  /* Init extensions */
-  gst_eglglessink_init_egl_exts (eglglessink);
+*/
 
   return;
 
@@ -1551,11 +1583,13 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
    * already if it meant to do so
    */
   if (!eglglessink->have_window) {
+/*
     if (!eglglessink->can_create_window) {
       GST_ERROR_OBJECT (eglglessink,
           "Have no window and we have been told not to create one!");
       goto HANDLE_ERROR;
     }
+*/
     GST_INFO_OBJECT (eglglessink,
         "No window. Will attempt internal window creation");
     if (!(window = gst_eglglessink_create_window (eglglessink, width, height))) {
@@ -1565,12 +1599,13 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
     gst_eglglessink_set_window_handle (GST_X_OVERLAY (eglglessink), window);
   }
 
-  if (!gst_eglglessink_init_egl_surface (eglglessink)) {
-    GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL surface from window");
-    goto HANDLE_ERROR;
+  if (!eglglessink->have_surface) {
+    if (!gst_eglglessink_init_egl_surface (eglglessink)) {
+      GST_ERROR_OBJECT (eglglessink, "Couldn't init EGL surface from window");
+      goto HANDLE_ERROR;
+    }
   }
-
-  gst_eglglessink_init_egl_exts (eglglessink);
+//  gst_eglglessink_init_egl_exts (eglglessink);
 
 SUCCEED:
   GST_INFO_OBJECT (eglglessink, "Setcaps succeed");
@@ -1719,6 +1754,7 @@ gst_eglglessink_init (GstEglGlesSink * eglglessink,
   eglglessink->have_surface = FALSE;
   eglglessink->have_vbo = FALSE;
   eglglessink->have_texture = FALSE;
+  eglglessink->egl_started = FALSE;
   eglglessink->running = FALSE; /* XXX: unused */
   eglglessink->can_create_window = TRUE;
   eglglessink->force_rendering_slow = FALSE;
index 80ae91d..6c255c0 100644 (file)
@@ -143,6 +143,7 @@ struct _GstEglGlesSink
   gboolean have_surface;;
   gboolean have_vbo;
   gboolean have_texture;
+  gboolean egl_started;
   gboolean running;
 
   GstEglGlesSinkRenderingPath rendering_path;