material-node: track if node owns reference on parent
authorRobert Bragg <robert@linux.intel.com>
Tue, 26 Oct 2010 16:43:16 +0000 (17:43 +0100)
committerRobert Bragg <robert@linux.intel.com>
Wed, 3 Nov 2010 17:28:45 +0000 (17:28 +0000)
MaterialNodes are used for the sparse graph of material state and layer
state. In the case of materials there is the idea of weak materials that
don't take a reference on their parent and in that case we need to be
careful not to unref our parent during
_cogl_material_node_unparent_real. This adds a has_parent_reference
member to the CoglMaterialNode struct so we now know when to skip the
unref.

clutter/cogl/cogl/cogl-material-private.h
clutter/cogl/cogl/cogl-material.c

index eb20b38..88dbfc0 100644 (file)
@@ -138,6 +138,10 @@ struct _CoglMaterialNode
   /* The parent material/layer */
   CoglMaterialNode *parent;
 
+  /* TRUE if the node took a strong reference on its parent. Weak
+   * materials for instance don't take a reference on their parent. */
+  gboolean has_parent_reference;
+
   /* As an optimization for creating leaf node materials/layers (the
    * most common) we don't require any list node allocations to link
    * to a single descendant. */
index 905e0e5..7203508 100644 (file)
@@ -127,6 +127,7 @@ _cogl_material_node_set_parent_real (CoglMaterialNode *node,
     }
 
   node->parent = parent;
+  node->has_parent_reference = take_strong_reference;
 
   /* Now that there is a consistent parent->child link we can remove
    * the parent reference if no reference was requested. If it turns
@@ -160,7 +161,8 @@ _cogl_material_node_unparent_real (CoglMaterialNode *node)
   else
     parent->children = g_list_remove (parent->children, node);
 
-  cogl_object_unref (parent);
+  if (node->has_parent_reference)
+    cogl_object_unref (parent);
 
   node->parent = NULL;
 }