Mesa (master): mesa: Dynamically allocate the matrix stack.

Eric Anholt anholt at kemper.freedesktop.org
Thu Aug 4 16:10:46 UTC 2016


Module: Mesa
Branch: master
Commit: 49741e1cd23c726f1956fe2b2e78a85ba8482385
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=49741e1cd23c726f1956fe2b2e78a85ba8482385

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug  2 12:48:47 2016 -0700

mesa: Dynamically allocate the matrix stack.

By allocating and initializing the matrices at context creation, the OS
couldn't even overcommit the pages.  This saves about 63k (out of 946k) of
maximum memory size according to massif on simulated vc4
glsl-algebraic-add-add-1.  It also means we could potentially relax the
maximum stack sizes, but that should be a separate commit.

v2: Drop redundant Top update, explain why the stack is small at init
    time.

Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/mesa/main/matrix.c | 28 ++++++++++++++++++++++++----
 src/mesa/main/mtypes.h |  1 +
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
index 293d50c..b30b983 100644
--- a/src/mesa/main/matrix.c
+++ b/src/mesa/main/matrix.c
@@ -243,6 +243,24 @@ _mesa_PushMatrix( void )
       }
       return;
    }
+   if (stack->Depth + 1 >= stack->StackSize) {
+      unsigned new_stack_size = stack->StackSize * 2;
+      unsigned i;
+      GLmatrix *new_stack = realloc(stack->Stack,
+                                    sizeof(*new_stack) * new_stack_size);
+
+      if (!new_stack) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushMatrix()");
+         return;
+      }
+
+      for (i = stack->StackSize; i < new_stack_size; i++)
+         _math_matrix_ctr(&new_stack[i]);
+
+      stack->Stack = new_stack;
+      stack->StackSize = new_stack_size;
+   }
+
    _math_matrix_copy( &stack->Stack[stack->Depth + 1],
                       &stack->Stack[stack->Depth] );
    stack->Depth++;
@@ -645,9 +663,10 @@ init_matrix_stack( struct gl_matrix_stack *stack,
    stack->Depth = 0;
    stack->MaxDepth = maxDepth;
    stack->DirtyFlag = dirtyFlag;
-   /* The stack */
-   stack->Stack = calloc(maxDepth, sizeof(GLmatrix));
-   for (i = 0; i < maxDepth; i++) {
+   /* The stack will be dynamically resized at glPushMatrix() time */
+   stack->Stack = calloc(1, sizeof(GLmatrix));
+   stack->StackSize = 1;
+   for (i = 0; i < stack->StackSize; i++) {
       _math_matrix_ctr(&stack->Stack[i]);
    }
    stack->Top = stack->Stack;
@@ -665,11 +684,12 @@ static void
 free_matrix_stack( struct gl_matrix_stack *stack )
 {
    GLuint i;
-   for (i = 0; i < stack->MaxDepth; i++) {
+   for (i = 0; i < stack->StackSize; i++) {
       _math_matrix_dtr(&stack->Stack[i]);
    }
    free(stack->Stack);
    stack->Stack = stack->Top = NULL;
+   stack->StackSize = 0;
 }
 
 /*@}*/
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 2647f8f..5b02fad 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3990,6 +3990,7 @@ struct gl_matrix_stack
 {
    GLmatrix *Top;      /**< points into Stack */
    GLmatrix *Stack;    /**< array [MaxDepth] of GLmatrix */
+   unsigned StackSize; /**< Number of elements in Stack */
    GLuint Depth;       /**< 0 <= Depth < MaxDepth */
    GLuint MaxDepth;    /**< size of Stack[] array */
    GLuint DirtyFlag;   /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */




More information about the mesa-commit mailing list