summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-07-06 12:45:26 +0100
committerNeil Roberts <neil@linux.intel.com>2011-07-07 02:10:24 +0100
commit2cfe64db73c437f8115b6f056d083072df00434b (patch)
tree12fae63400c2831766003c710653f2fcaa5f2e20
parenta8af207ddcf535f9b1d0a2e99999a9d68b06ea60 (diff)
downloadclutter-2cfe64db73c437f8115b6f056d083072df00434b.tar.gz
cogl-pipeline: Fix reference counting on promoting weak parents
When a copy is made of a weak pipeline it tries to promote the weak parent by taking a reference on that weak pipeline's parent. However promote_weak_ancestors was instead always taking a reference on the first parent, regardless of whether it was weak. The corresponding revert_weak_ancestors function which is supposed to undo the effect of promote_weak_ancestors only unref'd the parent if was weak. This meant that any non-weak pipeline copy would end up leaking a reference on its parent. This patch changes both functions to have a similar loop. It loops through all of the parents of the pipeline until it finds one that is not weak and refs or unrefs the *parent* of that pipeline instead of the pipeline itself. This is cherry-picked from 17a558a386 on Cogl git master.
-rw-r--r--clutter/cogl/cogl/cogl-pipeline.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/clutter/cogl/cogl/cogl-pipeline.c b/clutter/cogl/cogl/cogl-pipeline.c
index acce53683..5f2024ad2 100644
--- a/clutter/cogl/cogl/cogl-pipeline.c
+++ b/clutter/cogl/cogl/cogl-pipeline.c
@@ -394,37 +394,40 @@ _cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong)
g_return_if_fail (!strong->is_weak);
- for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent)
- {
- CoglPipeline *pipeline = COGL_PIPELINE (n);
+ /* If the parent of strong is weak, then we want to promote it by
+ taking a reference on strong's grandparent. We don't need to take
+ a reference on strong's direct parent */
- cogl_object_ref (pipeline);
+ if (COGL_PIPELINE_NODE (strong)->parent == NULL)
+ return;
- if (!pipeline->is_weak)
- return;
- }
+ for (n = COGL_PIPELINE_NODE (strong)->parent;
+ /* We can assume that all weak pipelines have a parent */
+ COGL_PIPELINE (n)->is_weak;
+ n = n->parent)
+ /* 'pipeline' is weak so we take a reference on its parent */
+ cogl_object_ref (n->parent);
}
static void
_cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong)
{
- CoglPipeline *parent = _cogl_pipeline_get_parent (strong);
CoglPipelineNode *n;
g_return_if_fail (!strong->is_weak);
- if (!parent || !parent->is_weak)
- return;
-
- for (n = COGL_PIPELINE_NODE (strong)->parent; n; n = n->parent)
- {
- CoglPipeline *pipeline = COGL_PIPELINE (n);
+ /* This reverts the effect of calling
+ _cogl_pipeline_promote_weak_ancestors */
- cogl_object_unref (pipeline);
+ if (COGL_PIPELINE_NODE (strong)->parent == NULL)
+ return;
- if (!pipeline->is_weak)
- return;
- }
+ for (n = COGL_PIPELINE_NODE (strong)->parent;
+ /* We can assume that all weak pipelines have a parent */
+ COGL_PIPELINE (n)->is_weak;
+ n = n->parent)
+ /* 'pipeline' is weak so we take a reference on its parent */
+ cogl_object_unref (n->parent);
}
/* XXX: Always have an eye out for opportunities to lower the cost of