summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/context.c281
-rw-r--r--src/mesa/main/dd.h15
-rw-r--r--src/mesa/main/teximage.c261
-rw-r--r--src/mesa/main/teximage.h15
-rw-r--r--src/mesa/main/texobj.c255
-rw-r--r--src/mesa/main/texobj.h19
-rw-r--r--src/mesa/main/texstore.c19
7 files changed, 477 insertions, 388 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index b9bbe651933..7c8befc0a80 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.194 2003/03/01 01:50:20 brianp Exp $ */
+/* $Id: context.c,v 1.195 2003/04/01 16:41:50 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -637,15 +637,14 @@ free_matrix_stack( struct matrix_stack *stack )
/*
* Allocate and initialize a shared context state structure.
*/
-static struct gl_shared_state *
-alloc_shared_state( void )
+static GLboolean
+alloc_shared_state( GLcontext *ctx )
{
- struct gl_shared_state *ss;
- GLboolean outOfMemory;
-
- ss = CALLOC_STRUCT(gl_shared_state);
+ struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
if (!ss)
- return NULL;
+ return GL_FALSE;
+
+ ctx->Shared = ss;
_glthread_INIT_MUTEX(ss->Mutex);
@@ -655,64 +654,66 @@ alloc_shared_state( void )
ss->Programs = _mesa_NewHashTable();
#endif
- /* Default Texture objects */
- outOfMemory = GL_FALSE;
+ ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
+ if (!ss->Default1D)
+ goto cleanup;
- ss->Default1D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_1D);
- if (!ss->Default1D) {
- outOfMemory = GL_TRUE;
- }
+ ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
+ if (!ss->Default2D)
+ goto cleanup;
- ss->Default2D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_2D);
- if (!ss->Default2D) {
- outOfMemory = GL_TRUE;
- }
+ ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
+ if (!ss->Default3D)
+ goto cleanup;
- ss->Default3D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_3D);
- if (!ss->Default3D) {
- outOfMemory = GL_TRUE;
- }
+ ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
+ if (!ss->DefaultCubeMap)
+ goto cleanup;
- ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0,
- GL_TEXTURE_CUBE_MAP_ARB);
- if (!ss->DefaultCubeMap) {
- outOfMemory = GL_TRUE;
- }
+ ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
+ if (!ss->DefaultRect)
+ goto cleanup;
- ss->DefaultRect = _mesa_alloc_texture_object(ss, 0,
- GL_TEXTURE_RECTANGLE_NV);
- if (!ss->DefaultRect) {
- outOfMemory = GL_TRUE;
- }
+#if 0
+ _mesa_save_texture_object(ctx, ss->Default1D);
+ _mesa_save_texture_object(ctx, ss->Default2D);
+ _mesa_save_texture_object(ctx, ss->Default3D);
+ _mesa_save_texture_object(ctx, ss->DefaultCubeMap);
+ _mesa_save_texture_object(ctx, ss->DefaultRect);
+#endif
+
+ /* Effectively bind the default textures to all texture units */
+ ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
+ ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- if (!ss->DisplayList || !ss->TexObjects
+ return GL_TRUE;
+
+ cleanup:
+ /* Ran out of memory at some point. Free everything and return NULL */
+ if (ss->DisplayList)
+ _mesa_DeleteHashTable(ss->DisplayList);
+ if (ss->TexObjects)
+ _mesa_DeleteHashTable(ss->TexObjects);
#if FEATURE_NV_vertex_program
- || !ss->Programs
+ if (ss->Programs)
+ _mesa_DeleteHashTable(ss->Programs);
#endif
- || outOfMemory) {
- /* Ran out of memory at some point. Free everything and return NULL */
- if (ss->DisplayList)
- _mesa_DeleteHashTable(ss->DisplayList);
- if (ss->TexObjects)
- _mesa_DeleteHashTable(ss->TexObjects);
- if (ss->Programs)
- _mesa_DeleteHashTable(ss->Programs);
- if (ss->Default1D)
- _mesa_free_texture_object(ss, ss->Default1D);
- if (ss->Default2D)
- _mesa_free_texture_object(ss, ss->Default2D);
- if (ss->Default3D)
- _mesa_free_texture_object(ss, ss->Default3D);
- if (ss->DefaultCubeMap)
- _mesa_free_texture_object(ss, ss->DefaultCubeMap);
- if (ss->DefaultRect)
- _mesa_free_texture_object(ss, ss->DefaultRect);
- FREE(ss);
- return NULL;
- }
- else {
- return ss;
- }
+ if (ss->Default1D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
+ if (ss->Default2D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
+ if (ss->Default3D)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
+ if (ss->DefaultCubeMap)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
+ if (ss->DefaultRect)
+ (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
+ if (ss)
+ _mesa_free(ss);
+ return GL_FALSE;
}
@@ -735,11 +736,19 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->DisplayList);
/* Free texture objects */
- while (ss->TexObjectList) {
- if (ctx->Driver.DeleteTexture)
- (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
- /* this function removes from linked list too! */
- _mesa_free_texture_object(ss, ss->TexObjectList);
+ ASSERT(ctx->Driver.DeleteTexture);
+ while (1) {
+ GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
+ if (texName) {
+ struct gl_texture_object *texObj = (struct gl_texture_object *)
+ _mesa_HashLookup(ss->TexObjects, texName);
+ ASSERT(texObj);
+ (*ctx->Driver.DeleteTexture)(ctx, texObj);
+ _mesa_HashRemove(ss->TexObjects, texName);
+ }
+ else {
+ break;
+ }
}
_mesa_DeleteHashTable(ss->TexObjects);
@@ -1529,99 +1538,48 @@ init_attrib_groups( GLcontext *ctx )
-/*
- * Allocate the proxy textures. If we run out of memory part way through
- * the allocations clean up and return GL_FALSE.
- * Return: GL_TRUE=success, GL_FALSE=failure
+/**
+ * Allocate the proxy textures for the given context.
+ * \param ctx the context to allocate proxies for.
+ * \return GL_TRUE if success, GL_FALSE if failure.
*/
static GLboolean
alloc_proxy_textures( GLcontext *ctx )
{
- GLboolean out_of_memory;
- GLint i;
+ ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
+ if (!ctx->Texture.Proxy1D)
+ goto cleanup;
- ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_1D);
- if (!ctx->Texture.Proxy1D) {
- return GL_FALSE;
- }
+ ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
+ if (!ctx->Texture.Proxy2D)
+ goto cleanup;
- ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_2D);
- if (!ctx->Texture.Proxy2D) {
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
- return GL_FALSE;
- }
+ ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
+ if (!ctx->Texture.Proxy3D)
+ goto cleanup;
- ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_3D);
- if (!ctx->Texture.Proxy3D) {
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
- return GL_FALSE;
- }
-
- ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0,
- GL_TEXTURE_CUBE_MAP_ARB);
- if (!ctx->Texture.ProxyCubeMap) {
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
- return GL_FALSE;
- }
+ ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
+ if (!ctx->Texture.ProxyCubeMap)
+ goto cleanup;
- ctx->Texture.ProxyRect = _mesa_alloc_texture_object(NULL, 0,
- GL_TEXTURE_RECTANGLE_NV);
- if (!ctx->Texture.ProxyRect) {
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
- _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
- return GL_FALSE;
- }
+ ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
+ if (!ctx->Texture.ProxyRect)
+ goto cleanup;
- out_of_memory = GL_FALSE;
- for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
- ctx->Texture.Proxy1D->Image[i] = _mesa_alloc_texture_image();
- ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image();
- ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image();
- ctx->Texture.ProxyCubeMap->Image[i] = _mesa_alloc_texture_image();
- if (!ctx->Texture.Proxy1D->Image[i]
- || !ctx->Texture.Proxy2D->Image[i]
- || !ctx->Texture.Proxy3D->Image[i]
- || !ctx->Texture.ProxyCubeMap->Image[i]) {
- out_of_memory = GL_TRUE;
- }
- }
- ctx->Texture.ProxyRect->Image[0] = _mesa_alloc_texture_image();
- if (!ctx->Texture.ProxyRect->Image[0])
- out_of_memory = GL_TRUE;
+ return GL_TRUE;
- if (out_of_memory) {
- for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
- if (ctx->Texture.Proxy1D->Image[i]) {
- _mesa_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
- }
- if (ctx->Texture.Proxy2D->Image[i]) {
- _mesa_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
- }
- if (ctx->Texture.Proxy3D->Image[i]) {
- _mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
- }
- if (ctx->Texture.ProxyCubeMap->Image[i]) {
- _mesa_free_texture_image(ctx->Texture.ProxyCubeMap->Image[i]);
- }
- }
- if (ctx->Texture.ProxyRect->Image[0]) {
- _mesa_free_texture_image(ctx->Texture.ProxyRect->Image[0]);
- }
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
- _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
- _mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
- _mesa_free_texture_object(NULL, ctx->Texture.ProxyRect);
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
- }
+ cleanup:
+ if (ctx->Texture.Proxy1D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
+ if (ctx->Texture.Proxy2D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
+ if (ctx->Texture.Proxy3D)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
+ if (ctx->Texture.ProxyCubeMap)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
+ if (ctx->Texture.ProxyRect)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
+ return GL_FALSE;
}
@@ -1695,14 +1653,23 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->DrawBuffer = NULL;
ctx->ReadBuffer = NULL;
+ /* Set these pointers to defaults now in case they're not set since
+ * we need them while creating the default textures.
+ */
+ if (!ctx->Driver.NewTextureObject)
+ ctx->Driver.NewTextureObject = _mesa_new_texture_object;
+ if (!ctx->Driver.DeleteTexture)
+ ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
+ if (!ctx->Driver.NewTextureImage)
+ ctx->Driver.NewTextureImage = _mesa_new_texture_image;
+
if (share_list) {
/* share state with another context */
ctx->Shared = share_list->Shared;
}
else {
/* allocate new, unshared state */
- ctx->Shared = alloc_shared_state();
- if (!ctx->Shared) {
+ if (!alloc_shared_state( ctx )) {
return GL_FALSE;
}
}
@@ -1710,13 +1677,6 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->Shared->RefCount++;
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- /* Effectively bind the default textures to all texture units */
- ctx->Shared->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ctx->Shared->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ctx->Shared->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
- ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
-
init_attrib_groups( ctx );
if (visual->doubleBufferMode) {
@@ -1837,6 +1797,7 @@ _mesa_initialize_context( GLcontext *ctx,
_glapi_add_entrypoint("glGetFenceivNV", 651);
_glapi_add_entrypoint("glFinishFenceNV", 652);
_glapi_add_entrypoint("glSetFenceNV", 653);
+ /* XXX add NV_fragment_program and ARB_vertex_program functions */
/* Find the larger of Mesa's dispatch table and libGL's dispatch table.
* In practice, this'll be the same for stand-alone Mesa. But for DRI
@@ -1997,11 +1958,11 @@ _mesa_free_context_data( GLcontext *ctx )
FREE( ctx->_ShineTabList );
/* Free proxy texture objects */
- _mesa_free_texture_object( NULL, ctx->Texture.Proxy1D );
- _mesa_free_texture_object( NULL, ctx->Texture.Proxy2D );
- _mesa_free_texture_object( NULL, ctx->Texture.Proxy3D );
- _mesa_free_texture_object( NULL, ctx->Texture.ProxyCubeMap );
- _mesa_free_texture_object( NULL, ctx->Texture.ProxyRect );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
_mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index d6f0da1c69e..59316ca0549 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -1,4 +1,4 @@
-/* $Id: dd.h,v 1.74 2002/10/11 17:41:04 brianp Exp $ */
+/* $Id: dd.h,v 1.75 2003/04/01 16:41:52 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -51,7 +51,6 @@ struct gl_pixelstore_attrib;
* Device Driver function table.
*/
struct dd_function_table {
-
const GLubyte * (*GetString)( GLcontext *ctx, GLenum name );
/* Return a string as needed by glGetString().
* Only the GL_RENDERER token must be implemented. Otherwise,
@@ -354,8 +353,12 @@ struct dd_function_table {
/* Called by glBindTexture().
*/
- void (*CreateTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
- /* Called when a texture object is created.
+ struct gl_texture_object * (*NewTextureObject)( GLcontext *ctx, GLuint name,
+ GLenum target );
+ /* Called to allocate a new texture object.
+ * NOTE: this function pointer should be initialized by drivers _BEFORE_
+ * calling _mesa_initialize_context() since context initialization involves
+ * allocating some texture objects!
*/
void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
@@ -363,6 +366,10 @@ struct dd_function_table {
* should free anything attached to the DriverData pointers.
*/
+ struct gl_texture_image * (*NewTextureImage)( GLcontext *ctx );
+ /* Called to allocate a new texture image object.
+ */
+
GLboolean (*IsTextureResident)( GLcontext *ctx,
struct gl_texture_object *t );
/* Called by glAreTextureResident().
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 3397a865cd5..cef81cb670d 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1,4 +1,4 @@
-/* $Id: teximage.c,v 1.126 2003/03/01 01:50:22 brianp Exp $ */
+/* $Id: teximage.c,v 1.127 2003/04/01 16:41:53 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -415,19 +415,26 @@ _mesa_set_tex_image(struct gl_texture_object *tObj,
-/*
+/**
* Return new gl_texture_image struct with all fields initialized to zero.
+ * Called via ctx->Driver.NewTextureImage() unless overriden by a device
+ * driver.
*/
struct gl_texture_image *
-_mesa_alloc_texture_image( void )
+_mesa_new_texture_image( GLcontext *ctx )
{
+ (void) ctx;
return CALLOC_STRUCT(gl_texture_image);
}
+/**
+ * Delete/free the given texture image and associated image data if it's not
+ * marked as client data.
+ */
void
-_mesa_free_texture_image( struct gl_texture_image *teximage )
+_mesa_delete_texture_image( struct gl_texture_image *teximage )
{
if (teximage->Data && !teximage->IsClientData) {
MESA_PBUFFER_FREE( teximage->Data );
@@ -577,6 +584,118 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
}
+/**
+ * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
+ * it and install it. Only return NULL if passed a bad parameter or run
+ * out of memory.
+ */
+struct gl_texture_image *
+_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level)
+{
+ struct gl_texture_image *texImage;
+ texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ if (!texImage) {
+ struct gl_texture_object *texObj;
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
+ return NULL;
+ }
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ ASSERT(texObj);
+ _mesa_set_tex_image(texObj, target, level, texImage);
+ }
+ return texImage;
+}
+
+
+/**
+ * Return pointer to the specified proxy texture image.
+ * Note that proxy textures are per-context, not per-texture unit.
+ * \return pointer to texture image or NULL if invalid target, invalid
+ * level, or out of memory.
+ */
+struct gl_texture_image *
+_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
+{
+ struct gl_texture_image *texImage;
+
+ if (level < 0 )
+ return NULL;
+
+ switch (target) {
+ case GL_PROXY_TEXTURE_1D:
+ if (level >= ctx->Const.MaxTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy1D->Image[level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy1D->Image[level] = texImage;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_2D:
+ if (level >= ctx->Const.MaxTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy2D->Image[level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy2D->Image[level] = texImage;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_3D:
+ if (level >= ctx->Const.Max3DTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.Proxy3D->Image[level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.Proxy3D->Image[level] = texImage;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ if (level >= ctx->Const.MaxCubeTextureLevels)
+ return NULL;
+ texImage = ctx->Texture.ProxyCubeMap->Image[level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.ProxyCubeMap->Image[level] = texImage;
+ }
+ return texImage;
+ case GL_PROXY_TEXTURE_RECTANGLE_NV:
+ if (level > 0)
+ return NULL;
+ texImage = ctx->Texture.ProxyRect->Image[level];
+ if (!texImage) {
+ texImage = ctx->Driver.NewTextureImage(ctx);
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
+ return NULL;
+ }
+ ctx->Texture.ProxyRect->Image[level] = texImage;
+ }
+ return texImage;
+ default:
+ return NULL;
+ }
+}
+
+
/*
* Return the maximum number of allows mipmap levels for the given
* texture target.
@@ -1167,10 +1286,8 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
if (destTex->IsCompressed) {
const struct gl_texture_unit *texUnit;
- const struct gl_texture_object *texObj;
const struct gl_texture_image *texImage;
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
@@ -1637,15 +1754,11 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- texObj->Image[level] = texImage;
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
@@ -1690,9 +1803,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
- clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
- }
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
}
else {
/* no error, set the tex image parameters */
@@ -1746,15 +1860,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- _mesa_set_tex_image(texObj, target, level, texImage);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
@@ -1803,11 +1912,10 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
- ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
- if (level >= 0 && level < maxLevels) {
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
- }
}
else {
/* no error, set the tex image parameters */
@@ -1852,15 +1960,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- texObj->Image[level] = texImage;
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
@@ -1904,9 +2007,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
- clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
- }
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
}
else {
/* no error, set the tex image parameters */
@@ -2102,14 +2206,10 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- _mesa_set_tex_image(texObj, target, level, texImage);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
@@ -2166,14 +2266,10 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- _mesa_set_tex_image(texObj, target, level, texImage);
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
/* free the old texture data */
@@ -2228,6 +2324,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
@@ -2264,6 +2361,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
@@ -2302,6 +2400,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ ASSERT(texImage);
/* If we have a border, xoffset=-1 is legal. Bias by border width */
xoffset += texImage->Border;
@@ -2509,15 +2608,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- texObj->Image[level] = texImage;
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
@@ -2549,9 +2643,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
- clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
- }
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
}
else {
/* store the teximage parameters */
@@ -2595,15 +2690,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- texObj->Image[level] = texImage;
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
@@ -2637,11 +2727,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
- ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
- if (level >= 0 && level < maxLevels) {
- clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
- }
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
}
else {
/* store the teximage parameters */
@@ -2682,15 +2771,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-
+ texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
if (!texImage) {
- texImage = _mesa_alloc_texture_image();
- texObj->Image[level] = texImage;
- if (!texImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
- return;
- }
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
+ return;
}
else if (texImage->Data && !texImage->IsClientData) {
MESA_PBUFFER_FREE(texImage->Data);
@@ -2723,9 +2807,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
}
if (error) {
/* if error, clear all proxy texture image parameters */
- if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
- clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
- }
+ struct gl_texture_image *texImage;
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
+ if (texImage)
+ clear_teximage_fields(texImage);
}
else {
/* store the teximage parameters */
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index 8cbc0d66152..7ab6810209d 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -1,4 +1,4 @@
-/* $Id: teximage.h,v 1.22 2002/10/18 18:03:07 brianp Exp $ */
+/* $Id: teximage.h,v 1.23 2003/04/01 16:41:54 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -40,11 +40,11 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format );
extern struct gl_texture_image *
-_mesa_alloc_texture_image( void );
+_mesa_new_texture_image( GLcontext *ctx );
extern void
-_mesa_free_texture_image( struct gl_texture_image *teximage );
+_mesa_delete_texture_image( struct gl_texture_image *teximage );
extern void
@@ -70,6 +70,15 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
GLenum target, GLint level);
+extern struct gl_texture_image *
+_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
+ GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level);
+
+
extern GLint
_mesa_max_texture_levels(GLcontext *ctx, GLenum target);
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index c845e8c7a3a..864752b6d98 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -1,4 +1,4 @@
-/* $Id: texobj.c,v 1.66 2003/03/10 00:26:24 brianp Exp $ */
+/* $Id: texobj.c,v 1.67 2003/04/01 16:41:55 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -37,23 +37,37 @@
#include "mtypes.h"
-/*
- * Allocate a new texture object and add it to the linked list of texture
- * objects. If name>0 then also insert the new texture object into the hash
- * table.
- * Input: shared - the shared GL state structure to contain the texture object
- * name - integer name for the texture object
- * target - either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
- * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV
- * zero is ok for the sake of GenTextures()
- * Return: pointer to new texture object
+/**
+ * Allocate and initialize a new texture object
+ * Called via ctx->Driver.NewTextureObject, unless overridden by a device
+ * driver.
+ * \param ctx the rendering context
+ * \param name the integer name for the texture object
+ * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
+ * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV
+ * zero is ok for the sake of GenTextures()
+ * \return pointer to new texture object
*/
struct gl_texture_object *
-_mesa_alloc_texture_object( struct gl_shared_state *shared,
- GLuint name, GLenum target )
+_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target )
{
struct gl_texture_object *obj;
+ obj = CALLOC_STRUCT(gl_texture_object);
+ _mesa_initialize_texture_object(obj, name, target);
+ return obj;
+}
+
+/**
+ * Initialize a texture object to default values.
+ * \param obj the texture object
+ * \param name the texture name
+ * \param target the texture target
+ */
+void
+_mesa_initialize_texture_object( struct gl_texture_object *obj,
+ GLuint name, GLenum target )
+{
ASSERT(target == 0 ||
target == GL_TEXTURE_1D ||
target == GL_TEXTURE_2D ||
@@ -61,114 +75,124 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
target == GL_TEXTURE_CUBE_MAP_ARB ||
target == GL_TEXTURE_RECTANGLE_NV);
- obj = CALLOC_STRUCT(gl_texture_object);
-
- if (obj) {
- /* init the non-zero fields */
- _glthread_INIT_MUTEX(obj->Mutex);
- obj->RefCount = 1;
- obj->Name = name;
- obj->Target = target;
- obj->Priority = 1.0F;
- if (target == GL_TEXTURE_RECTANGLE_NV) {
- obj->WrapS = GL_CLAMP_TO_EDGE;
- obj->WrapT = GL_CLAMP_TO_EDGE;
- obj->WrapR = GL_CLAMP_TO_EDGE;
- obj->MinFilter = GL_LINEAR;
- }
- else {
- obj->WrapS = GL_REPEAT;
- obj->WrapT = GL_REPEAT;
- obj->WrapR = GL_REPEAT;
- obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
- }
- obj->MagFilter = GL_LINEAR;
- obj->MinLod = -1000.0;
- obj->MaxLod = 1000.0;
- obj->BaseLevel = 0;
- obj->MaxLevel = 1000;
- obj->MaxAnisotropy = 1.0;
- obj->CompareFlag = GL_FALSE; /* SGIX_shadow */
- obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */
- obj->CompareMode = GL_LUMINANCE; /* ARB_shadow */
- obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
- obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
- obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
- _mesa_init_colortable(&obj->Palette);
-
- /* insert into linked list */
- if (shared) {
- _glthread_LOCK_MUTEX(shared->Mutex);
- obj->Next = shared->TexObjectList;
- shared->TexObjectList = obj;
- _glthread_UNLOCK_MUTEX(shared->Mutex);
- }
-
- if (name > 0) {
- /* insert into hash table */
- _mesa_HashInsert(shared->TexObjects, name, obj);
- }
+ /* init the non-zero fields */
+ _glthread_INIT_MUTEX(obj->Mutex);
+ obj->RefCount = 1;
+ obj->Name = name;
+ obj->Target = target;
+ obj->Priority = 1.0F;
+ if (target == GL_TEXTURE_RECTANGLE_NV) {
+ obj->WrapS = GL_CLAMP_TO_EDGE;
+ obj->WrapT = GL_CLAMP_TO_EDGE;
+ obj->WrapR = GL_CLAMP_TO_EDGE;
+ obj->MinFilter = GL_LINEAR;
}
- return obj;
+ else {
+ obj->WrapS = GL_REPEAT;
+ obj->WrapT = GL_REPEAT;
+ obj->WrapR = GL_REPEAT;
+ obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
+ }
+ obj->MagFilter = GL_LINEAR;
+ obj->MinLod = -1000.0;
+ obj->MaxLod = 1000.0;
+ obj->BaseLevel = 0;
+ obj->MaxLevel = 1000;
+ obj->MaxAnisotropy = 1.0;
+ obj->CompareFlag = GL_FALSE; /* SGIX_shadow */
+ obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */
+ obj->CompareMode = GL_LUMINANCE; /* ARB_shadow */
+ obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
+ obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
+ obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
+ _mesa_init_colortable(&obj->Palette);
}
/*
- * Deallocate a texture object struct and remove it from the given
- * shared GL state.
- * Input: shared - the shared GL state to which the object belongs
- * t - the texture object to delete
+ * Deallocate a texture object. It should have already been removed from
+ * the texture object pool.
+ * \param texObj the texture object to deallocate
*/
-void _mesa_free_texture_object( struct gl_shared_state *shared,
- struct gl_texture_object *t )
+void
+_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
{
- struct gl_texture_object *tprev, *tcurr;
+ GLuint i;
- assert(t);
-
- /* unlink t from the linked list */
- if (shared) {
- _glthread_LOCK_MUTEX(shared->Mutex);
- tprev = NULL;
- tcurr = shared->TexObjectList;
- while (tcurr) {
- if (tcurr==t) {
- if (tprev) {
- tprev->Next = t->Next;
- }
- else {
- shared->TexObjectList = t->Next;
- }
- break;
- }
- tprev = tcurr;
- tcurr = tcurr->Next;
+ (void) ctx;
+
+ assert(texObj);
+
+ _mesa_free_colortable_data(&texObj->Palette);
+
+ /* free the texture images */
+ for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
+ if (texObj->Image[i]) {
+ _mesa_delete_texture_image( texObj->Image[i] );
}
- _glthread_UNLOCK_MUTEX(shared->Mutex);
}
- if (t->Name) {
- /* remove from hash table */
- _mesa_HashRemove(shared->TexObjects, t->Name);
+ /* destroy the mutex -- it may have allocated memory (eg on bsd) */
+ _glthread_DESTROY_MUTEX(texObj->Mutex);
+
+ /* free this object */
+ _mesa_free(texObj);
+}
+
+
+/**
+ * Add the given texture object to the texture object pool.
+ */
+void
+_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
+{
+ /* insert into linked list */
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ texObj->Next = ctx->Shared->TexObjectList;
+ ctx->Shared->TexObjectList = texObj;
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ if (texObj->Name > 0) {
+ /* insert into hash table */
+ _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
}
+}
- _mesa_free_colortable_data(&t->Palette);
- /* free the texture images */
- {
- GLuint i;
- for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
- if (t->Image[i]) {
- _mesa_free_texture_image( t->Image[i] );
+/**
+ * Remove the given texture object from the texture object pool.
+ * Do not deallocate the texture object though.
+ */
+void
+_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
+{
+ struct gl_texture_object *tprev, *tcurr;
+
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+
+ /* unlink from the linked list */
+ tprev = NULL;
+ tcurr = ctx->Shared->TexObjectList;
+ while (tcurr) {
+ if (tcurr == texObj) {
+ if (tprev) {
+ tprev->Next = texObj->Next;
}
+ else {
+ ctx->Shared->TexObjectList = texObj->Next;
+ }
+ break;
}
+ tprev = tcurr;
+ tcurr = tcurr->Next;
}
- /* destroy the mutex -- it may have allocated memory (eg on bsd) */
- _glthread_DESTROY_MUTEX(t->Mutex);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- /* free this object */
- FREE( t );
+ if (texObj->Name > 0) {
+ /* remove from hash table */
+ _mesa_HashRemove(ctx->Shared->TexObjects, texObj->Name);
+ }
}
@@ -531,10 +555,16 @@ _mesa_GenTextures( GLsizei n, GLuint *texName )
}
/* Allocate new, empty texture objects */
- for (i=0;i<n;i++) {
+ for (i = 0; i < n; i++) {
+ struct gl_texture_object *texObj;
GLuint name = first + i;
GLenum target = 0;
- (void) _mesa_alloc_texture_object( ctx->Shared, name, target);
+ texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
+ return;
+ }
+ _mesa_save_texture_object(ctx, texObj);
}
_glthread_UNLOCK_MUTEX(GenTexturesLock);
@@ -610,9 +640,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *texName)
if (delObj->RefCount == 0) {
ASSERT(delObj->Name != 0);
- if (ctx->Driver.DeleteTexture)
- (*ctx->Driver.DeleteTexture)( ctx, delObj );
- _mesa_free_texture_object(ctx->Shared, delObj);
+ _mesa_remove_texture_object(ctx, delObj);
+ ASSERT(ctx->Driver.DeleteTexture);
+ (*ctx->Driver.DeleteTexture)(ctx, delObj);
}
}
}
@@ -717,12 +747,12 @@ _mesa_BindTexture( GLenum target, GLuint texName )
}
else {
/* if this is a new texture id, allocate a texture object now */
- newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName,
- target);
+ newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target);
if (!newTexObj) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
return;
}
+ _mesa_save_texture_object(ctx, newTexObj);
}
newTexObj->Target = target;
}
@@ -762,10 +792,9 @@ _mesa_BindTexture( GLenum target, GLuint texName )
assert(oldTexObj->RefCount >= 0);
if (oldTexObj->RefCount == 0) {
assert(oldTexObj->Name != 0);
- if (ctx->Driver.DeleteTexture) {
- (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
- }
- _mesa_free_texture_object(ctx->Shared, oldTexObj);
+ _mesa_remove_texture_object(ctx, oldTexObj);
+ ASSERT(ctx->Driver.DeleteTexture);
+ (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
}
}
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 050caff23fd..ff46187809d 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -1,4 +1,4 @@
-/* $Id: texobj.h,v 1.8 2002/06/17 23:36:31 brianp Exp $ */
+/* $Id: texobj.h,v 1.9 2003/04/01 16:41:55 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -38,23 +38,28 @@
*/
extern struct gl_texture_object *
-_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
- GLenum target );
+_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target );
+extern void
+_mesa_initialize_texture_object( struct gl_texture_object *obj,
+ GLuint name, GLenum target );
extern void
-_mesa_free_texture_object( struct gl_shared_state *shared,
- struct gl_texture_object *t );
+_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
+extern void
+_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
+
+extern void
+_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
extern void
_mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
-
extern void
_mesa_test_texobj_completeness( const GLcontext *ctx,
- struct gl_texture_object *t );
+ struct gl_texture_object *obj );
/*
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 117696896eb..08e625bc0d4 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -1,4 +1,4 @@
-/* $Id: texstore.c,v 1.54 2003/03/04 19:16:23 brianp Exp $ */
+/* $Id: texstore.c,v 1.55 2003/04/01 16:41:55 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -482,6 +482,7 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
baseInternalFormat == GL_ALPHA ||
baseInternalFormat == GL_RGB ||
baseInternalFormat == GL_RGBA ||
+ baseInternalFormat == GL_COLOR_INDEX ||
baseInternalFormat == GL_DEPTH_COMPONENT);
if (transferOps & IMAGE_CONVOLUTION_BIT) {
@@ -1274,16 +1275,12 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
GLint internalFormat, GLenum format, GLenum type,
GLint width, GLint height, GLint depth, GLint border)
{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
(void) format;
(void) type;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
+ texImage = _mesa_get_proxy_tex_image(ctx, target, level);
/* We always pass.
* The core Mesa code will have already tested the image size, etc.
@@ -2011,14 +2008,10 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
}
/* get dest gl_texture_image */
- dstImage = _mesa_select_tex_image(ctx, texUnit, target, level+1);
+ dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
if (!dstImage) {
- dstImage = _mesa_alloc_texture_image();
- if (!dstImage) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
- return;
- }
- _mesa_set_tex_image(texObj, target, level + 1, dstImage);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+ return;
}
/* Free old image data */