diff --git a/cogl/cogl/cogl-pipeline-debug.c b/cogl/cogl/cogl-pipeline-debug.c index 2e4ff7074..b5f7c5bf4 100644 --- a/cogl/cogl/cogl-pipeline-debug.c +++ b/cogl/cogl/cogl-pipeline-debug.c @@ -49,10 +49,10 @@ typedef struct int indent; } PrintDebugState; -static gboolean -dump_layer_cb (CoglNode *node, void *user_data) +static void +dump_layer_cb (CoglPipelineLayer *layer, + gpointer user_data) { - CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node); PrintDebugState *state = user_data; int layer_id = *state->node_id_ptr; PrintDebugState state_out; @@ -62,7 +62,7 @@ dump_layer_cb (CoglNode *node, void *user_data) if (state->parent_id >= 0) g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n", state->indent, "", - layer->parent_instance.parent, + layer->parent, layer); g_string_append_printf (state->graph, @@ -116,11 +116,12 @@ dump_layer_cb (CoglNode *node, void *user_data) state_out.graph = state->graph; state_out.indent = state->indent + 2; - _cogl_pipeline_node_foreach_child (COGL_NODE (layer), - dump_layer_cb, - &state_out); - - return TRUE; + for (CoglPipelineLayer *child = layer->first_child; + child != NULL; + child = child->next_sibling) + { + dump_layer_cb (child, &state_out); + } } static gboolean @@ -264,7 +265,7 @@ _cogl_debug_dump_pipelines_dot_file (const char *filename, layer_state.parent_id = -1; layer_state.node_id_ptr = &layer_id; layer_state.indent = 0; - dump_layer_cb ((CoglNode *)ctx->default_layer_0, &layer_state); + dump_layer_cb (ctx->default_layer_0, &layer_state); pipeline_state.graph = graph; pipeline_state.parent_id = -1; diff --git a/cogl/cogl/cogl-pipeline-layer-private.h b/cogl/cogl/cogl-pipeline-layer-private.h index b93904405..7b887496e 100644 --- a/cogl/cogl/cogl-pipeline-layer-private.h +++ b/cogl/cogl/cogl-pipeline-layer-private.h @@ -35,7 +35,6 @@ #include "cogl/cogl-private.h" #include "cogl/cogl-pipeline.h" -#include "cogl/cogl-node-private.h" #include "cogl/cogl-texture.h" #include "cogl/cogl-pipeline-layer-state.h" #include "cogl/cogl-pipeline-snippet-private.h" @@ -218,7 +217,13 @@ struct _CoglPipelineLayer * the state relating to a given pipeline or layer may actually be * owned by one if is ancestors in the tree. We have a common data * type to track the tree hierarchy so we can share code... */ - CoglNode parent_instance; + GObject parent_instance; + + CoglPipelineLayer *parent; + CoglPipelineLayer *prev_sibling; + CoglPipelineLayer *next_sibling; + CoglPipelineLayer *first_child; + CoglPipelineLayer *last_child; /* Some layers have a pipeline owner, which is to say that the layer * is referenced in that pipelines->layer_differences list. A layer @@ -264,7 +269,7 @@ struct _CoglPipelineLayer struct _CoglPipelineLayerClass { - CoglNodeClass parent_class; + GObjectClass parent_class; }; @@ -280,8 +285,7 @@ _cogl_pipeline_init_default_layers (CoglContext *ctx); static inline CoglPipelineLayer * _cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer) { - CoglNode *parent_node = COGL_NODE (layer)->parent; - return COGL_PIPELINE_LAYER (parent_node); + return layer->parent; } CoglPipelineLayer * diff --git a/cogl/cogl/cogl-pipeline-layer.c b/cogl/cogl/cogl-pipeline-layer.c index 22769d060..4ae35b33a 100644 --- a/cogl/cogl/cogl-pipeline-layer.c +++ b/cogl/cogl/cogl-pipeline-layer.c @@ -41,20 +41,42 @@ #include "cogl/cogl-pipeline-layer-private.h" #include "cogl/cogl-pipeline-layer-state-private.h" #include "cogl/cogl-pipeline-layer-state.h" -#include "cogl/cogl-node-private.h" #include "cogl/cogl-context-private.h" #include "cogl/cogl-texture-private.h" #include -G_DEFINE_FINAL_TYPE (CoglPipelineLayer, cogl_pipeline_layer, COGL_TYPE_NODE) +G_DEFINE_FINAL_TYPE (CoglPipelineLayer, cogl_pipeline_layer, G_TYPE_OBJECT) + +static void +cogl_pipeline_layer_unparent (CoglPipelineLayer *layer) +{ + g_autoptr (CoglPipelineLayer) parent = g_steal_pointer (&layer->parent); + + if (parent) + { + if (parent->first_child == layer) + parent->first_child = layer->next_sibling; + + if (parent->last_child == layer) + parent->last_child = layer->prev_sibling; + + if (layer->prev_sibling) + layer->prev_sibling->next_sibling = layer->next_sibling; + if (layer->next_sibling) + layer->next_sibling->prev_sibling = layer->prev_sibling; + } + + layer->prev_sibling = NULL; + layer->next_sibling = NULL; +} static void cogl_pipeline_layer_dispose (GObject *object) { CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (object); - _cogl_pipeline_node_unparent (COGL_NODE (layer)); + cogl_pipeline_layer_unparent (layer); if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA && layer->texture != NULL) @@ -371,8 +393,7 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, { /* Identify the case where the layer is new with no owner or * dependants and so we don't need to do anything. */ - if (_cogl_list_empty (&COGL_NODE (layer)->children) && - layer->owner == NULL) + if (layer->first_child == NULL && layer->owner == NULL) goto init_layer_state; /* We only allow a NULL required_owner for new layers */ @@ -393,8 +414,7 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, * they have dependants - either direct children, or another * pipeline as an owner. */ - if (!_cogl_list_empty (&COGL_NODE (layer)->children) || - layer->owner != required_owner) + if (layer->first_child != NULL || layer->owner != required_owner) { CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer); if (layer->owner == required_owner) @@ -468,10 +488,32 @@ static void _cogl_pipeline_layer_set_parent (CoglPipelineLayer *layer, CoglPipelineLayer *parent) { - /* Chain up */ - _cogl_pipeline_node_set_parent (COGL_NODE (layer), - COGL_NODE (parent), - TRUE); + g_autoptr (CoglPipelineLayer) owned_parent = NULL; + + g_assert (COGL_IS_PIPELINE_LAYER (layer)); + g_assert (COGL_IS_PIPELINE_LAYER (parent)); + + if (layer->parent == parent) + return; + + if (layer->parent) + { + owned_parent = g_object_ref (layer->parent); + cogl_pipeline_layer_unparent (layer); + } + + layer->parent = g_object_ref (parent); + + if (parent->first_child) + { + parent->first_child->prev_sibling = layer; + layer->next_sibling = parent->first_child; + } + else + { + parent->last_child = layer; + } + parent->first_child = layer; } CoglPipelineLayer * diff --git a/cogl/cogl/cogl-pipeline.c b/cogl/cogl/cogl-pipeline.c index 7c80af9d1..48eed1388 100644 --- a/cogl/cogl/cogl-pipeline.c +++ b/cogl/cogl/cogl-pipeline.c @@ -2558,7 +2558,7 @@ deep_copy_layer_cb (CoglPipelineLayer *src_layer, differences ^= to_copy; } - src_layer = COGL_PIPELINE_LAYER (COGL_NODE (src_layer)->parent); + src_layer = src_layer->parent; } return TRUE;