mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 19:20:35 +00:00
[718/906] shader: make it possible to unref in the non-GL thread
This commit is contained in:
parent
a5b877fb13
commit
11b810fcf5
3 changed files with 54 additions and 124 deletions
|
@ -93,33 +93,9 @@ 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;
|
||||
|
||||
shader = GST_GL_SHADER (object);
|
||||
|
||||
if (shader->display) {
|
||||
gst_object_unref (shader->display);
|
||||
shader->display = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gst_gl_shader_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_shader_finalize (GObject * object)
|
||||
{
|
||||
GstGLShader *shader;
|
||||
GstGLShaderPrivate *priv;
|
||||
|
||||
shader = GST_GL_SHADER (object);
|
||||
priv = shader->priv;
|
||||
|
||||
GST_TRACE ("finalizing shader %u", priv->program_handle);
|
||||
|
||||
g_free (priv->vertex_src);
|
||||
g_free (priv->fragment_src);
|
||||
GstGLShaderPrivate *priv = shader->priv;
|
||||
|
||||
/* release shader objects */
|
||||
gst_gl_shader_release (shader);
|
||||
|
@ -136,11 +112,34 @@ gst_gl_shader_finalize (GObject * object)
|
|||
}
|
||||
|
||||
GST_DEBUG ("shader deleted %u", priv->program_handle);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_shader_finalize (GObject * object)
|
||||
{
|
||||
GstGLShader *shader;
|
||||
GstGLShaderPrivate *priv;
|
||||
|
||||
shader = GST_GL_SHADER (object);
|
||||
priv = shader->priv;
|
||||
|
||||
GST_TRACE ("finalizing shader %u", priv->program_handle);
|
||||
|
||||
g_free (priv->vertex_src);
|
||||
g_free (priv->fragment_src);
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue