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.
This commit is contained in:
Brian Paul
2004-09-14 20:40:55 +00:00
parent d84f09306c
commit f18fc68707
2 changed files with 23 additions and 11 deletions

View File

@@ -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] */

View File

@@ -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.
*