From 117ef6baff7c644534d2c1ab81ef77b937ab4ec7 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 1 Nov 2010 22:07:11 +0000 Subject: [PATCH] matrix-stack: use GArray instead of GSList for stack In some micro-benchmarks testing journal throughput the list manipulation jumps pretty high in the profile. This replaces the GSList usage with a GArray instead which is effectively a grow only allocation that means we avoid ongoing allocations while manipulating the stack mid-scene. --- cogl/cogl-matrix-stack.c | 55 +++++++++++++--------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/cogl/cogl-matrix-stack.c b/cogl/cogl-matrix-stack.c index c55439a7e..c65ec74ea 100644 --- a/cogl/cogl-matrix-stack.c +++ b/cogl/cogl-matrix-stack.c @@ -53,7 +53,7 @@ typedef struct { */ struct _CoglMatrixStack { - GSList *stack; + GArray *stack; /* which state does GL have, NULL if unknown */ CoglMatrixState *flushed_state; @@ -61,28 +61,17 @@ struct _CoglMatrixStack }; /* XXX: this doesn't initialize the matrix! */ -static CoglMatrixState* -_cogl_matrix_state_new (void) +static void +_cogl_matrix_state_init (CoglMatrixState *state) { - CoglMatrixState *state; - - state = g_slice_new (CoglMatrixState); state->push_count = 0; state->is_identity = FALSE; - - return state; } -static void -_cogl_matrix_state_destroy (CoglMatrixState *state) -{ - g_slice_free (CoglMatrixState, state); -} - -static CoglMatrixState* +static CoglMatrixState * _cogl_matrix_stack_top (CoglMatrixStack *stack) { - return stack->stack->data; + return &g_array_index (stack->stack, CoglMatrixState, stack->stack->len - 1); } /* XXX: @@ -115,7 +104,10 @@ _cogl_matrix_stack_top_mutable (CoglMatrixStack *stack, state->push_count -= 1; - new_top = _cogl_matrix_state_new (); + g_array_set_size (stack->stack, stack->stack->len + 1); + new_top = &g_array_index (stack->stack, CoglMatrixState, + stack->stack->len - 1); + _cogl_matrix_state_init (new_top); if (initialize) { @@ -128,8 +120,6 @@ _cogl_matrix_stack_top_mutable (CoglMatrixStack *stack, stack->flushed_state = new_top; } - stack->stack = g_slist_prepend (stack->stack, new_top); - return new_top; } @@ -141,28 +131,20 @@ _cogl_matrix_stack_new (void) stack = g_slice_new0 (CoglMatrixStack); - state = _cogl_matrix_state_new (); + stack->stack = g_array_sized_new (FALSE, FALSE, + sizeof (CoglMatrixState), 10); + g_array_set_size (stack->stack, 1); + state = &g_array_index (stack->stack, CoglMatrixState, 0); + _cogl_matrix_state_init (state); state->is_identity = TRUE; - stack->stack = g_slist_prepend (stack->stack, state); - return stack; } void _cogl_matrix_stack_destroy (CoglMatrixStack *stack) { - while (stack->stack) - { - CoglMatrixState *state; - - state = stack->stack->data; - _cogl_matrix_state_destroy (state); - stack->stack = - g_slist_delete_link (stack->stack, - stack->stack); - } - + g_array_free (stack->stack, TRUE); g_slice_free (CoglMatrixStack, stack); } @@ -192,7 +174,7 @@ _cogl_matrix_stack_pop (CoglMatrixStack *stack) } else { - if (stack->stack->next == NULL) + if (stack->stack->len == 1) { g_warning ("Too many matrix pops"); return; @@ -203,10 +185,7 @@ _cogl_matrix_stack_pop (CoglMatrixStack *stack) stack->flushed_state = NULL; } - stack->stack = - g_slist_delete_link (stack->stack, - stack->stack); - _cogl_matrix_state_destroy (state); + g_array_set_size (stack->stack, stack->stack->len - 1); } }