From f18fc687071a71a6f821a779a83b435f80d55b64 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 14 Sep 2004 20:40:55 +0000 Subject: Repeatedly deleting a texture ID with glDeleteTextures() could lead to a crash. Added a DeletePending flag to texture object struct to fix that. Other misc clean-ups. --- src/mesa/main/mtypes.h | 1 + src/mesa/main/texobj.c | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ba32faad70..3e5c04415d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1147,6 +1147,7 @@ struct gl_texture_image { struct gl_texture_object { _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ + GLboolean DeletePending; /**< Has glDeleteTexture been called? */ GLuint Name; /**< an unsigned integer */ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ GLfloat Priority; /**< in [0,1] */ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 74a5fdc06e..5e02f3b04c 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -5,7 +5,7 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.2 * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * @@ -72,7 +72,7 @@ _mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target ) /** - * Initialize a texture object to default values. + * Initialize a new texture object to default values. * \param obj the texture object * \param name the texture name * \param target the texture target @@ -88,9 +88,9 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, target == GL_TEXTURE_CUBE_MAP_ARB || target == GL_TEXTURE_RECTANGLE_NV); + _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ _glthread_INIT_MUTEX(obj->Mutex); - _mesa_bzero(obj, sizeof(*obj)); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -138,8 +138,6 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) (void) ctx; - assert(texObj); - _mesa_free_colortable_data(&texObj->Palette); /* free the texture images */ @@ -703,12 +701,16 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) } ctx->NewState |= _NEW_TEXTURE; - /* Decrement reference count and delete if zero */ - delObj->RefCount--; - ASSERT(delObj->RefCount >= 0); + /* If user hasn't already tried to delete the texture... */ + if (!delObj->DeletePending) { + delObj->DeletePending = GL_TRUE; + delObj->RefCount--; + ASSERT(delObj->RefCount >= 0); + } + /* See if we can really delete the texture now */ if (delObj->RefCount == 0) { - ASSERT(delObj->Name != 0); + ASSERT(delObj->Name != 0); /* Never delete default tex objects */ _mesa_remove_texture_object(ctx, delObj); ASSERT(ctx->Driver.DeleteTexture); (*ctx->Driver.DeleteTexture)(ctx, delObj); @@ -718,6 +720,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) } } + /** * Bind a named texture to a texturing target. * @@ -747,6 +750,9 @@ _mesa_BindTexture( GLenum target, GLuint texName ) _mesa_debug(ctx, "glBindTexture %s %d\n", _mesa_lookup_enum_by_nr(target), (GLint) texName); + /* + * Get pointer to currently bound texture object (oldTexObj) + */ switch (target) { case GL_TEXTURE_1D: oldTexObj = texUnit->Current1D; @@ -875,16 +881,21 @@ _mesa_BindTexture( GLenum target, GLuint texName ) if (ctx->Driver.BindTexture) (*ctx->Driver.BindTexture)( ctx, target, newTexObj ); + /* Decrement the reference count on the old texture and check if it's + * time to delete it. + */ oldTexObj->RefCount--; - assert(oldTexObj->RefCount >= 0); + ASSERT(oldTexObj->RefCount >= 0); if (oldTexObj->RefCount == 0) { - assert(oldTexObj->Name != 0); + ASSERT(oldTexObj->Name != 0); + ASSERT(oldTexObj->DeletePending); _mesa_remove_texture_object(ctx, oldTexObj); ASSERT(ctx->Driver.DeleteTexture); (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); } } + /** * Set texture priorities. * -- cgit v1.2.3