nouveau: unbreak nv40
[mesa.git] / src / mesa / main / texobj.c
index cfe9229cdb19b14c1a2a45cb32e3e247dc499bc1..1d27cd3f7c69aaedca0496241cf0d3f3197c4711 100644 (file)
@@ -697,7 +697,11 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
       if (textures[i] > 0) {
          struct gl_texture_object *delObj
             = _mesa_lookup_texture(ctx, textures[i]);
+
          if (delObj) {
+           GLboolean delete;
+
+           _mesa_lock_texture(ctx, delObj);
 
             /* Check if texture is bound to any framebuffer objects.
              * If so, unbind.
@@ -724,7 +728,14 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
              * XXX all RefCount accesses should be protected by a mutex.
              */
             delObj->RefCount--;
-            if (delObj->RefCount == 0) {
+           delete = (delObj->RefCount == 0);
+           _mesa_unlock_texture(ctx, delObj);
+
+           /* We know that refcount went to zero above, so this is
+            * the only pointer left to delObj, so we don't have to
+            * worry about locking any more:
+            */
+            if (delete) {
                ASSERT(delObj->Name != 0); /* Never delete default tex objs */
                ASSERT(ctx->Driver.DeleteTexture);
                (*ctx->Driver.DeleteTexture)(ctx, delObj);
@@ -754,7 +765,7 @@ void GLAPIENTRY
 _mesa_BindTexture( GLenum target, GLuint texName )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLuint unit = ctx->Texture.CurrentUnit;
+   const GLuint unit = ctx->Texture.CurrentUnit;
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    struct gl_texture_object *oldTexObj;
    struct gl_texture_object *newTexObj = NULL;
@@ -796,12 +807,15 @@ _mesa_BindTexture( GLenum target, GLuint texName )
          return;
    }
 
-   if (oldTexObj->Name == texName)
+   if (oldTexObj->Name == texName) {
       /* XXX this might be wrong.  If the texobj is in use by another
        * context and a texobj parameter was changed, this might be our
        * only chance to update this context's hardware state.
+       * Note that some applications re-bind the same texture a lot so we
+       * want to handle that case quickly.
        */
       return;   /* rebinding the same texture- no change */
+   }
 
    /*
     * Get pointer to new texture object (newTexObj)
@@ -1049,4 +1063,30 @@ _mesa_IsTexture( GLuint texture )
    return t && t->Target;
 }
 
+/* Simplest implementation of texture locking: Grab the a new mutex in
+ * the shared context.  Examine the shared context state timestamp and
+ * if there has been a change, set the appropriate bits in
+ * ctx->NewState.
+ *
+ * See also _mesa_lock/unlock_texture in texobj.h
+ */
+void _mesa_lock_context_textures( GLcontext *ctx )
+{
+   _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
+
+   if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
+      ctx->NewState |= _NEW_TEXTURE;
+      ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp;
+   }
+}
+
+
+void _mesa_unlock_context_textures( GLcontext *ctx )
+{
+   assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
+   _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
+}
+
 /*@}*/
+
+