Mesa (master): mesa: reference counting for gl_array_object

Brian Paul brianp at kemper.freedesktop.org
Thu May 7 20:35:43 UTC 2009


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

Author: Brian Paul <brianp at vmware.com>
Date:   Thu May  7 13:52:26 2009 -0600

mesa: reference counting for gl_array_object

Every kind of object that can be shared by multiple contexts should be
refcounted.

---

 src/mesa/main/arrayobj.c |   67 +++++++++++++++++++++++++++++++++++++++++++---
 src/mesa/main/arrayobj.h |   23 +++++++++++-----
 src/mesa/main/mtypes.h   |    3 +-
 src/mesa/main/varray.c   |    4 +-
 4 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c
index 2646c12..71f4216 100644
--- a/src/mesa/main/arrayobj.c
+++ b/src/mesa/main/arrayobj.c
@@ -94,10 +94,69 @@ void
 _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj )
 {
    (void) ctx;
+   _glthread_DESTROY_MUTEX(obj->Mutex);
    _mesa_free(obj);
 }
 
 
+/**
+ * Set ptr to arrayObj w/ reference counting.
+ */
+void
+_mesa_reference_array_object(GLcontext *ctx,
+                             struct gl_array_object **ptr,
+                             struct gl_array_object *arrayObj)
+{
+   if (*ptr == arrayObj)
+      return;
+
+   if (*ptr) {
+      /* Unreference the old array object */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_array_object *oldObj = *ptr;
+
+      _glthread_LOCK_MUTEX(oldObj->Mutex);
+      ASSERT(oldObj->RefCount > 0);
+      oldObj->RefCount--;
+#if 0
+      printf("ArrayObj %p %d DECR to %d\n",
+             (void *) oldObj, oldObj->Name, oldObj->RefCount);
+#endif
+      deleteFlag = (oldObj->RefCount == 0);
+      _glthread_UNLOCK_MUTEX(oldObj->Mutex);
+
+      if (deleteFlag) {
+	 ASSERT(ctx->Driver.DeleteArrayObject);
+         ctx->Driver.DeleteArrayObject(ctx, oldObj);
+      }
+
+      *ptr = NULL;
+   }
+   ASSERT(!*ptr);
+
+   if (arrayObj) {
+      /* reference new array object */
+      _glthread_LOCK_MUTEX(arrayObj->Mutex);
+      if (arrayObj->RefCount == 0) {
+         /* this array's being deleted (look just above) */
+         /* Not sure this can every really happen.  Warn if it does. */
+         _mesa_problem(NULL, "referencing deleted array object");
+         *ptr = NULL;
+      }
+      else {
+         arrayObj->RefCount++;
+#if 0
+         printf("ArrayObj %p %d INCR to %d\n",
+                (void *) arrayObj, arrayObj->Name, arrayObj->RefCount);
+#endif
+         *ptr = arrayObj;
+      }
+      _glthread_UNLOCK_MUTEX(arrayObj->Mutex);
+   }
+}
+
+
+
 static void
 init_array(GLcontext *ctx,
            struct gl_client_array *array, GLint size, GLint type)
@@ -130,6 +189,9 @@ _mesa_initialize_array_object( GLcontext *ctx,
 
    obj->Name = name;
 
+   _glthread_INIT_MUTEX(obj->Mutex);
+   obj->RefCount = 1;
+
    /* Init the individual arrays */
    init_array(ctx, &obj->Vertex, 4, GL_FLOAT);
    init_array(ctx, &obj->Normal, 3, GL_FLOAT);
@@ -227,7 +289,6 @@ _mesa_BindVertexArrayAPPLE( GLuint id )
       if (!newObj) {
          /* If this is a new array object id, allocate an array object now.
 	  */
-
 	 newObj = (*ctx->Driver.NewArrayObject)(ctx, id);
          if (!newObj) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
@@ -237,11 +298,9 @@ _mesa_BindVertexArrayAPPLE( GLuint id )
       }
    }
 
-
    ctx->NewState |= _NEW_ARRAY;
    ctx->Array.NewState |= _NEW_ARRAY_ALL;
-   ctx->Array.ArrayObj = newObj;
-
+   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj);
 
    /* Pass BindVertexArray call to device driver */
    if (ctx->Driver.BindArrayObject && newObj)
diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h
index c7d66ec..9c4036a 100644
--- a/src/mesa/main/arrayobj.h
+++ b/src/mesa/main/arrayobj.h
@@ -41,17 +41,26 @@
  * Internal functions
  */
 
-struct gl_array_object * _mesa_new_array_object( GLcontext *ctx,
-    GLuint name );
+extern struct gl_array_object *
+_mesa_new_array_object( GLcontext *ctx, GLuint name );
 
-void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj );
+extern void
+_mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj );
 
-void _mesa_initialize_array_object( GLcontext *ctx,
-    struct gl_array_object *obj, GLuint name );
+extern void
+_mesa_reference_array_object(GLcontext *ctx,
+                             struct gl_array_object **ptr,
+                             struct gl_array_object *arrayObj);
 
-void _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj );
+extern void
+_mesa_initialize_array_object( GLcontext *ctx,
+                               struct gl_array_object *obj, GLuint name );
 
-void _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj );
+extern void
+_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj );
+
+extern void
+_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj );
 
 
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index b24366d..d11df53 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1557,7 +1557,8 @@ struct gl_array_object
    /** Name of the array object as received from glGenVertexArrayAPPLE. */
    GLuint Name;
 
-   /** XXX Need a refcount here */
+   GLint RefCount;
+   _glthread_Mutex Mutex;
 
    /** Conventional vertex arrays */
    /*@{*/
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 4d153b1..a9c9162 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -1039,7 +1039,7 @@ void
 _mesa_init_varray(GLcontext *ctx)
 {
    ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
-   ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj;
-
+   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
+                                ctx->Array.DefaultArrayObj);
    ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
 }




More information about the mesa-commit mailing list