[718/906] shader: make it possible to unref in the non-GL thread
authorMatthew Waters <ystreet00@gmail.com>
Thu, 27 Jun 2013 14:34:48 +0000 (00:34 +1000)
committerMatthew Waters <ystreet00@gmail.com>
Sat, 15 Mar 2014 17:36:56 +0000 (18:36 +0100)
gst-libs/gst/gl/gstglshader.c
gst-libs/gst/gl/gstglutils.c
gst/gl/gstgleffects.c

index 6579a5b..b94890b 100644 (file)
@@ -93,18 +93,25 @@ GST_DEBUG_CATEGORY_STATIC (gst_gl_shader_debug);
 G_DEFINE_TYPE_WITH_CODE (GstGLShader, gst_gl_shader, G_TYPE_OBJECT, DEBUG_INIT);
 
 static void
-gst_gl_shader_dispose (GObject * object)
+_cleanup_shader (GstGLDisplay * display, GstGLShader * shader)
 {
-  GstGLShader *shader;
+  GstGLShaderPrivate *priv = shader->priv;
 
-  shader = GST_GL_SHADER (object);
+  /* release shader objects */
+  gst_gl_shader_release (shader);
 
-  if (shader->display) {
-    gst_object_unref (shader->display);
-    shader->display = NULL;
+  /* delete program */
+  if (priv->program_handle) {
+    GST_TRACE ("finalizing program shader %u", priv->program_handle);
+
+    priv->vtable.DeleteProgram (priv->program_handle);
+    /* err = glGetError (); */
+    /* GST_WARNING ("error: 0x%x", err);  */
+    /* glGetObjectParameteriv(priv->program_handle, GL_OBJECT_DELETE_STATUS_, &status); */
+    /* GST_INFO ("program deletion status:%s", status == GL_TRUE ? "true" : "false" ); */
   }
 
-  G_OBJECT_CLASS (gst_gl_shader_parent_class)->dispose (object);
+  GST_DEBUG ("shader deleted %u", priv->program_handle);
 }
 
 static void
@@ -121,26 +128,18 @@ gst_gl_shader_finalize (GObject * object)
   g_free (priv->vertex_src);
   g_free (priv->fragment_src);
 
-  /* release shader objects */
-  gst_gl_shader_release (shader);
-
-  /* delete program */
-  if (priv->program_handle) {
-    GST_TRACE ("finalizing program shader %u", priv->program_handle);
-
-    priv->vtable.DeleteProgram (priv->program_handle);
-    /* err = glGetError (); */
-    /* GST_WARNING ("error: 0x%x", err);  */
-    /* glGetObjectParameteriv(priv->program_handle, GL_OBJECT_DELETE_STATUS_, &status); */
-    /* GST_INFO ("program deletion status:%s", status == GL_TRUE ? "true" : "false" ); */
-  }
-
-  GST_DEBUG ("shader deleted %u", priv->program_handle);
+  gst_gl_display_thread_add (shader->display,
+      (GstGLDisplayThreadFunc) _cleanup_shader, shader);
 
   priv->fragment_handle = 0;
   priv->vertex_handle = 0;
   priv->program_handle = 0;
 
+  if (shader->display) {
+    gst_object_unref (shader->display);
+    shader->display = NULL;
+  }
+
   G_OBJECT_CLASS (gst_gl_shader_parent_class)->finalize (object);
 }
 
@@ -196,7 +195,6 @@ gst_gl_shader_class_init (GstGLShaderClass * klass)
   g_type_class_add_private (klass, sizeof (GstGLShaderPrivate));
 
   obj_class->finalize = gst_gl_shader_finalize;
-  obj_class->dispose = gst_gl_shader_dispose;
   obj_class->set_property = gst_gl_shader_set_property;
   obj_class->get_property = gst_gl_shader_get_property;
 
index d36b525..a9c4a19 100644 (file)
@@ -55,15 +55,6 @@ static GstVideoFormat gen_texture_video_format;
 
 static GLuint *del_texture;
 
-/* action gen and del shader */
-static const gchar *gen_shader_fragment_source;
-static const gchar *gen_shader_vertex_source;
-static GstGLShader *gen_shader;
-static GstGLShader *del_shader;
-
-static void _gen_shader (GstGLDisplay * display);
-static void _del_shader (GstGLDisplay * display);
-
 static gchar *error_message;
 
 static void
@@ -425,36 +416,41 @@ gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer)
   gst_object_unref (frame);
 }
 
+static void
+_compile_shader (GstGLDisplay * display, GstGLShader ** shader)
+{
+  GError *error = NULL;
+
+  gst_gl_shader_compile (*shader, &error);
+  if (error) {
+    gst_gl_display_set_error (display, "%s", error->message);
+    g_error_free (error);
+    error = NULL;
+    gst_gl_display_clear_shader (display);
+    gst_object_unref (*shader);
+    *shader = NULL;
+  }
+}
 
 /* Called by glfilter */
 gboolean
-gst_gl_display_gen_shader (GstGLDisplay * display,
-    const gchar * shader_vertex_source,
-    const gchar * shader_fragment_source, GstGLShader ** shader)
+gst_gl_display_gen_shader (GstGLDisplay * display, const gchar * vert_src,
+    const gchar * frag_src, GstGLShader ** shader)
 {
-  gboolean alive;
-  GstGLWindow *window;
+  g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE);
+  g_return_val_if_fail (shader != NULL, FALSE);
 
-  gst_gl_display_lock (display);
+  *shader = gst_gl_shader_new (display);
 
-  window = gst_gl_display_get_window_unlocked (display);
-  if (gst_gl_window_is_running (window)) {
-    gen_shader_vertex_source = shader_vertex_source;
-    gen_shader_fragment_source = shader_fragment_source;
-    gst_gl_window_send_message (window,
-        GST_GL_WINDOW_CB (_gen_shader), display);
-    if (shader)
-      *shader = gen_shader;
-    gen_shader = NULL;
-    gen_shader_vertex_source = NULL;
-    gen_shader_fragment_source = NULL;
-  }
-  alive = gst_gl_window_is_running (window);
+  if (frag_src)
+    gst_gl_shader_set_fragment_source (*shader, frag_src);
+  if (vert_src)
+    gst_gl_shader_set_vertex_source (*shader, vert_src);
 
-  gst_object_unref (window);
-  gst_gl_display_unlock (display);
+  gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _compile_shader,
+      shader);
 
-  return alive;
+  return *shader != NULL;
 }
 
 void
@@ -482,67 +478,5 @@ gst_gl_display_get_error (void)
 void
 gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
 {
-  GstGLWindow *window;
-
-  gst_gl_display_lock (display);
-
-  window = gst_gl_display_get_window_unlocked (display);
-  if (gst_gl_window_is_running (window)) {
-    del_shader = shader;
-    gst_gl_window_send_message (window,
-        GST_GL_WINDOW_CB (_del_shader), display);
-  }
-
-  gst_object_unref (window);
-  gst_gl_display_unlock (display);
-}
-
-/* Called in the gl thread */
-static void
-_gen_shader (GstGLDisplay * display)
-{
-  const GstGLFuncs *gl = display->gl_vtable;
-
-  GST_TRACE ("Generating shader %" GST_PTR_FORMAT, gen_shader);
-
-  if (gl->CreateProgramObject || gl->CreateProgram) {
-    if (gen_shader_vertex_source || gen_shader_fragment_source) {
-      GError *error = NULL;
-
-      gen_shader = gst_gl_shader_new (display);
-
-      if (gen_shader_vertex_source)
-        gst_gl_shader_set_vertex_source (gen_shader, gen_shader_vertex_source);
-
-      if (gen_shader_fragment_source)
-        gst_gl_shader_set_fragment_source (gen_shader,
-            gen_shader_fragment_source);
-
-      gst_gl_shader_compile (gen_shader, &error);
-      if (error) {
-        gst_gl_display_set_error (display, "%s", error->message);
-        g_error_free (error);
-        error = NULL;
-        gst_gl_display_clear_shader (display);
-        gst_object_unref (gen_shader);
-        gen_shader = NULL;
-      }
-    }
-  } else {
-    gst_gl_display_set_error (display,
-        "One of the filter required ARB_fragment_shader");
-    gen_shader = NULL;
-  }
-}
-
-/* Called in the gl thread */
-static void
-_del_shader (GstGLDisplay * display)
-{
-  GST_TRACE ("Deleting shader %" GST_PTR_FORMAT, del_shader);
-
-  if (del_shader) {
-    gst_object_unref (del_shader);
-    del_shader = NULL;
-  }
+  gst_object_unref (shader);
 }
index 8d953b6..7627fce 100644 (file)
@@ -451,9 +451,7 @@ gst_gl_effects_init_resources (GstGLFilter * filter)
 static gboolean
 gst_gl_effects_on_init_gl_context (GstGLFilter * filter)
 {
-  /* check that your hardware supports shader
-   * if not the pipeline correctly shut down */
-  return gst_gl_display_gen_shader (filter->display, 0, 0, NULL);
+  return TRUE;
 }
 
 static gboolean