mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
[718/906] shader: make it possible to unref in the non-GL thread
This commit is contained in:
parent
71c8edf9c0
commit
5b13d0ebf4
2 changed files with 53 additions and 121 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);
|
G_DEFINE_TYPE_WITH_CODE (GstGLShader, gst_gl_shader, G_TYPE_OBJECT, DEBUG_INIT);
|
||||||
|
|
||||||
static void
|
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* release shader objects */
|
/* release shader objects */
|
||||||
gst_gl_shader_release (shader);
|
gst_gl_shader_release (shader);
|
||||||
|
@ -136,11 +112,34 @@ gst_gl_shader_finalize (GObject * object)
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("shader deleted %u", priv->program_handle);
|
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->fragment_handle = 0;
|
||||||
priv->vertex_handle = 0;
|
priv->vertex_handle = 0;
|
||||||
priv->program_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);
|
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));
|
g_type_class_add_private (klass, sizeof (GstGLShaderPrivate));
|
||||||
|
|
||||||
obj_class->finalize = gst_gl_shader_finalize;
|
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->set_property = gst_gl_shader_set_property;
|
||||||
obj_class->get_property = gst_gl_shader_get_property;
|
obj_class->get_property = gst_gl_shader_get_property;
|
||||||
|
|
||||||
|
|
|
@ -55,15 +55,6 @@ static GstVideoFormat gen_texture_video_format;
|
||||||
|
|
||||||
static GLuint *del_texture;
|
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 gchar *error_message;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -425,36 +416,41 @@ gst_gl_display_del_fbo (GstGLDisplay * display, GLuint fbo, GLuint depth_buffer)
|
||||||
gst_object_unref (frame);
|
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 */
|
/* Called by glfilter */
|
||||||
gboolean
|
gboolean
|
||||||
gst_gl_display_gen_shader (GstGLDisplay * display,
|
gst_gl_display_gen_shader (GstGLDisplay * display, const gchar * vert_src,
|
||||||
const gchar * shader_vertex_source,
|
const gchar * frag_src, GstGLShader ** shader)
|
||||||
const gchar * shader_fragment_source, GstGLShader ** shader)
|
|
||||||
{
|
{
|
||||||
gboolean alive;
|
g_return_val_if_fail (frag_src != NULL || vert_src != NULL, FALSE);
|
||||||
GstGLWindow *window;
|
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 (frag_src)
|
||||||
if (gst_gl_window_is_running (window)) {
|
gst_gl_shader_set_fragment_source (*shader, frag_src);
|
||||||
gen_shader_vertex_source = shader_vertex_source;
|
if (vert_src)
|
||||||
gen_shader_fragment_source = shader_fragment_source;
|
gst_gl_shader_set_vertex_source (*shader, vert_src);
|
||||||
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);
|
|
||||||
|
|
||||||
gst_object_unref (window);
|
gst_gl_display_thread_add (display, (GstGLDisplayThreadFunc) _compile_shader,
|
||||||
gst_gl_display_unlock (display);
|
shader);
|
||||||
|
|
||||||
return alive;
|
return *shader != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -482,67 +478,5 @@ gst_gl_display_get_error (void)
|
||||||
void
|
void
|
||||||
gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
|
gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
|
||||||
{
|
{
|
||||||
GstGLWindow *window;
|
gst_object_unref (shader);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue