[Cogl] [PATCH] matrix-stack: Prune stack entries when loading a replacement matrix
Robert Bragg
robert at sixbynine.org
Fri May 18 07:20:47 PDT 2012
Ah, yep this looks sensible.
Reviewed-by: Robert Bragg <robert at linux.intel.com>
regards,
- Robert
On Thu, May 17, 2012 at 11:41 PM, Neil Roberts <neil at linux.intel.com> wrote:
> Previously if an application does not use the matrix stack as a stack
> but instead just loads its own matrices for each frame using
> cogl_framebuffer_set_modelview_matrix then it will continously push
> OP_LOAD entries on the stack and the stack will grow forever. This
> patch fixes that use case by resetting the top of the stack to the
> last save entry whenever something is pushed that replaces the
> previous matrix on the stack.
> ---
> cogl/cogl-matrix-stack.c | 66 ++++++++++++++++++++++++++++++++++-----------
> 1 files changed, 50 insertions(+), 16 deletions(-)
>
> diff --git a/cogl/cogl-matrix-stack.c b/cogl/cogl-matrix-stack.c
> index 14a9040..2d61a5e 100644
> --- a/cogl/cogl-matrix-stack.c
> +++ b/cogl/cogl-matrix-stack.c
> @@ -69,6 +69,34 @@ _cogl_matrix_stack_push_entry (CoglMatrixStack *stack,
> return entry;
> }
>
> +static void *
> +_cogl_matrix_stack_push_replacement_entry (CoglMatrixStack *stack,
> + size_t size,
> + CoglMatrixOp operation)
> +{
> + CoglMatrixEntry *old_top = stack->last_entry;
> + CoglMatrixEntry *new_top;
> +
> + /* This would only be called for operations that completely replace
> + * the matrix. In that case we don't need to keep a reference to
> + * anything up to the last save entry. This optimisation could be
> + * important for applications that aren't using the stack but
> + * instead just perform their own matrix manipulations and load a
> + * new stack every frame. If this optimisation isn't done then the
> + * stack would just grow endlessly. See the comments
> + * _cogl_matrix_stack_pop for a description of how popping works. */
> + for (new_top = old_top;
> + new_top->op != COGL_MATRIX_OP_SAVE && new_top->parent;
> + new_top = new_top->parent)
> + ;
> +
> + _cogl_matrix_entry_ref (new_top);
> + _cogl_matrix_entry_unref (old_top);
> + stack->last_entry = new_top;
> +
> + return _cogl_matrix_stack_push_entry (stack, size, operation);
> +}
> +
> void
> _cogl_matrix_entry_identity_init (CoglMatrixEntry *entry)
> {
> @@ -81,9 +109,9 @@ _cogl_matrix_entry_identity_init (CoglMatrixEntry *entry)
> void
> _cogl_matrix_stack_load_identity (CoglMatrixStack *stack)
> {
> - _cogl_matrix_stack_push_entry (stack,
> - sizeof (CoglMatrixEntry),
> - COGL_MATRIX_OP_LOAD_IDENTITY);
> + _cogl_matrix_stack_push_replacement_entry (stack,
> + sizeof (CoglMatrixEntry),
> + COGL_MATRIX_OP_LOAD_IDENTITY);
> }
>
> void
> @@ -192,9 +220,10 @@ _cogl_matrix_stack_set (CoglMatrixStack *stack,
> {
> CoglMatrixEntryLoad *entry;
>
> - entry = _cogl_matrix_stack_push_entry (stack,
> - sizeof (CoglMatrixEntryLoad),
> - COGL_MATRIX_OP_LOAD);
> + entry =
> + _cogl_matrix_stack_push_replacement_entry (stack,
> + sizeof (CoglMatrixEntryLoad),
> + COGL_MATRIX_OP_LOAD);
>
> entry->matrix =
> _cogl_magazine_chunk_alloc (_cogl_matrix_stack_matrices_magazine);
> @@ -213,9 +242,10 @@ _cogl_matrix_stack_frustum (CoglMatrixStack *stack,
> {
> CoglMatrixEntryLoad *entry;
>
> - entry = _cogl_matrix_stack_push_entry (stack,
> - sizeof (CoglMatrixEntryLoad),
> - COGL_MATRIX_OP_LOAD);
> + entry =
> + _cogl_matrix_stack_push_replacement_entry (stack,
> + sizeof (CoglMatrixEntryLoad),
> + COGL_MATRIX_OP_LOAD);
>
> entry->matrix =
> _cogl_magazine_chunk_alloc (_cogl_matrix_stack_matrices_magazine);
> @@ -235,9 +265,10 @@ _cogl_matrix_stack_perspective (CoglMatrixStack *stack,
> {
> CoglMatrixEntryLoad *entry;
>
> - entry = _cogl_matrix_stack_push_entry (stack,
> - sizeof (CoglMatrixEntryLoad),
> - COGL_MATRIX_OP_LOAD);
> + entry =
> + _cogl_matrix_stack_push_replacement_entry (stack,
> + sizeof (CoglMatrixEntryLoad),
> + COGL_MATRIX_OP_LOAD);
>
> entry->matrix =
> _cogl_magazine_chunk_alloc (_cogl_matrix_stack_matrices_magazine);
> @@ -258,9 +289,10 @@ _cogl_matrix_stack_orthographic (CoglMatrixStack *stack,
> {
> CoglMatrixEntryLoad *entry;
>
> - entry = _cogl_matrix_stack_push_entry (stack,
> - sizeof (CoglMatrixEntryLoad),
> - COGL_MATRIX_OP_LOAD);
> + entry =
> + _cogl_matrix_stack_push_replacement_entry (stack,
> + sizeof (CoglMatrixEntryLoad),
> + COGL_MATRIX_OP_LOAD);
>
> entry->matrix =
> _cogl_magazine_chunk_alloc (_cogl_matrix_stack_matrices_magazine);
> @@ -605,7 +637,9 @@ _cogl_matrix_stack_new (void)
>
> stack->last_entry = NULL;
>
> - _cogl_matrix_stack_load_identity (stack);
> + _cogl_matrix_stack_push_entry (stack,
> + sizeof (CoglMatrixEntry),
> + COGL_MATRIX_OP_LOAD_IDENTITY);
>
> return _cogl_matrix_stack_object_new (stack);
> }
> --
> 1.7.3.16.g9464b
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list