From f2080f099e2a05b05cd0adb2f204c1917adae0f2 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 11 Jan 2011 10:23:59 +0000 Subject: [PATCH] shader: Don't notify properties when finalizing shaders clutter_shader_finalize() was calling clutter_shader_release() which in turn notifies "compiled". GObject was complaining that we were trying to _ref() an object that was in _finalize(). #0 g_log (log_domain=0x3e15c4 "GLib-GObject", log_level=G_LOG_LEVEL_CRITICAL, format=0x76c938 "%s: assertion `%s' failed") at gmessages.h:97 #1 0x0070777d in g_return_if_fail_warning ( log_domain=0x3e15c4 "GLib-GObject", pretty_function=0x3e37a4 "g_object_ref", expression=0x3e2a00 "object->ref_count > 0") at gmessages.c:586 #2 0x003b862b in g_object_ref (_object=0x8567af0) at gobject.c:2615 #3 0x003bd238 in g_object_notify_by_pspec (object=0x8567af0, pspec=0x87ea2f0) at gobject.c:1075 #4 0x00b6500b in clutter_shader_release (shader=0x8567af0) at ./clutter-shader.c:612 #5 0x00b659b9 in clutter_shader_finalize (object=0x8567af0) at ./clutter-shader.c:107 Then, let's split release in two, with an _internal() version that does not notify "compiled" and use it from dispose (as the object is still usable after a call to release_internal(). http://bugzilla.clutter-project.org/show_bug.cgi?id=2512 --- clutter/clutter-shader.c | 61 +++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/clutter/clutter-shader.c b/clutter/clutter-shader.c index c4cfd67..e2109c7 100644 --- a/clutter/clutter-shader.c +++ b/clutter/clutter-shader.c @@ -95,6 +95,31 @@ static GParamSpec *obj_props[PROP_LAST]; G_DEFINE_TYPE (ClutterShader, clutter_shader, G_TYPE_OBJECT); +static inline void +clutter_shader_release_internal (ClutterShader *shader) +{ + ClutterShaderPrivate *priv = shader->priv; + + if (!priv->compiled) + return; + + g_assert (priv->program != COGL_INVALID_HANDLE); + + if (priv->vertex_is_glsl && priv->vertex_shader != COGL_INVALID_HANDLE) + cogl_handle_unref (priv->vertex_shader); + + if (priv->fragment_is_glsl && priv->fragment_shader != COGL_INVALID_HANDLE) + cogl_handle_unref (priv->fragment_shader); + + if (priv->program != COGL_INVALID_HANDLE) + cogl_handle_unref (priv->program); + + priv->vertex_shader = COGL_INVALID_HANDLE; + priv->fragment_shader = COGL_INVALID_HANDLE; + priv->program = COGL_INVALID_HANDLE; + priv->compiled = FALSE; +} + static void clutter_shader_finalize (GObject *object) { @@ -104,8 +129,6 @@ clutter_shader_finalize (GObject *object) shader = CLUTTER_SHADER (object); priv = shader->priv; - clutter_shader_release (shader); - clutter_shaders_list = g_list_remove (clutter_shaders_list, object); g_free (priv->fragment_source); @@ -115,6 +138,16 @@ clutter_shader_finalize (GObject *object) } static void +clutter_shader_dispose (GObject *object) +{ + ClutterShader *shader = CLUTTER_SHADER (object); + + clutter_shader_release_internal (shader); + + G_OBJECT_CLASS (clutter_shader_parent_class)->finalize (object); +} + +static void clutter_shader_set_property (GObject *object, guint prop_id, const GValue *value, @@ -197,6 +230,7 @@ clutter_shader_class_init (ClutterShaderClass *klass) GParamSpec *pspec = NULL; object_class->finalize = clutter_shader_finalize; + object_class->dispose = clutter_shader_dispose; object_class->set_property = clutter_shader_set_property; object_class->get_property = clutter_shader_get_property; object_class->constructor = clutter_shader_constructor; @@ -584,30 +618,9 @@ clutter_shader_compile (ClutterShader *shader, void clutter_shader_release (ClutterShader *shader) { - ClutterShaderPrivate *priv; - g_return_if_fail (CLUTTER_IS_SHADER (shader)); - priv = shader->priv; - - if (!priv->compiled) - return; - - g_assert (priv->program != COGL_INVALID_HANDLE); - - if (priv->vertex_is_glsl && priv->vertex_shader != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->vertex_shader); - - if (priv->fragment_is_glsl && priv->fragment_shader != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->fragment_shader); - - if (priv->program != COGL_INVALID_HANDLE) - cogl_handle_unref (priv->program); - - priv->vertex_shader = COGL_INVALID_HANDLE; - priv->fragment_shader = COGL_INVALID_HANDLE; - priv->program = COGL_INVALID_HANDLE; - priv->compiled = FALSE; + clutter_shader_release_internal (shader); _clutter_notify_by_pspec (G_OBJECT (shader), obj_props[PROP_COMPILED]); } -- 2.7.4