diff options
| -rw-r--r-- | src/mesa/main/arrayobj.c | 67 | ||||
| -rw-r--r-- | src/mesa/main/arrayobj.h | 23 | ||||
| -rw-r--r-- | src/mesa/main/mtypes.h | 3 | ||||
| -rw-r--r-- | src/mesa/main/varray.c | 4 | 
4 files changed, 84 insertions, 13 deletions
| diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b04095fd16..ccb5b8e157 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) @@ -129,6 +188,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); @@ -226,7 +288,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"); @@ -236,11 +297,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 c7d66ec166..9c4036af5a 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 ed6b1062bd..50dc2def87 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,6 +1557,9 @@ struct gl_array_object     /** Name of the array object as received from glGenVertexArrayAPPLE. */     GLuint Name; +   GLint RefCount; +   _glthread_Mutex Mutex; +     /** Conventional vertex arrays */     /*@{*/     struct gl_client_array Vertex; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 106252e460..72b3e834b3 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1050,7 +1050,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 */  } | 
