summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-07-06 12:28:07 +0100
committerNeil Roberts <neil@linux.intel.com>2011-07-06 16:52:46 +0100
commit17a558a386d41444b926f9e8bec46f74d437745a (patch)
tree760222a0c8114e14cef4f11c69b460cc8f8be90e
parent2f0a20cdb5f1dcfde9b0c9fd51dfcea6a2117e8c (diff)
downloadcogl-17a558a386d41444b926f9e8bec46f74d437745a.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. Signed-off-by: Robert Bragg <robert@linux.intel.com>
-rw-r--r--cogl/cogl-pipeline.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
index db9d29b1..ce082032 100644
--- a/cogl/cogl-pipeline.c
+++ b/cogl/cogl-pipeline.c
@@ -375,37 +375,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)
+ /* 'n' 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)
+ /* 'n' is weak so we unref its parent */
+ cogl_object_unref (n->parent);
}
/* XXX: Always have an eye out for opportunities to lower the cost of