r300: Make sure to drop current hardware state reference to texture objects.
authorMichel Dänzer <daenzer@vmware.com>
Thu, 14 May 2009 09:07:49 +0000 (11:07 +0200)
committerMichel Dänzer <daenzer@vmware.com>
Thu, 14 May 2009 09:13:06 +0000 (11:13 +0200)
Fixes potential texture object leaks.

src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_texstate.c

index 12bee1a8fbbb7688e1d62a70b2dbc4874acb11a7..8f0effd83e2726ca2383f8f359ee15941f22462e 100644 (file)
@@ -43,6 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/matrix.h"
 #include "main/extensions.h"
 #include "main/state.h"
+#include "main/texobj.h"
 #include "main/bufferobj.h"
 
 #include "swrast/swrast.h"
@@ -500,6 +501,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
        r300ContextPtr r300 = (r300ContextPtr) driContextPriv->driverPrivate;
        radeonContextPtr radeon = (radeonContextPtr) r300;
        radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
+       int i;
 
        if (RADEON_DEBUG & DEBUG_DRI) {
                fprintf(stderr, "Destroying context !\n");
@@ -553,6 +555,11 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
                        assert(is_empty_list(&r300->swapped));
                }
 
+                /* Drop texture object references from current hardware state */
+               for (i = 0; i < 8; i++) {
+                       _mesa_reference_texobj(&r300->state.texture.unit[i].texobj, NULL);
+               }
+
                radeonCleanupContext(&r300->radeon);
 
 #ifdef USER_BUFFERS
index abe613e27bce12d6d98a24340b73e758260307a6..f6ae4b675b860f3fc474a30b63f10d7d07dbfb3e 100644 (file)
@@ -557,12 +557,15 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-       struct gl_texture_object *tObj = texUnit->_Current;
-       r300TexObjPtr t = (r300TexObjPtr) tObj->DriverData;
+       struct gl_texture_object *tObj = texUnit->_ReallyEnabled ?
+               texUnit->_Current : NULL;
+       r300TexObjPtr t = tObj ? (r300TexObjPtr) tObj->DriverData : NULL;
 
        /* Fallback if there's a texture border */
-       if (tObj->Image[0][tObj->BaseLevel]->Border > 0)
-               return GL_FALSE;
+       if (tObj && tObj->Image[0][tObj->BaseLevel]->Border > 0) {
+               tObj = NULL;
+               t = NULL;
+       }
 
        /* Update state if this is a different texture object to last
         * time.
@@ -579,11 +582,14 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit)
                }
 
                _mesa_reference_texobj(&rmesa->state.texture.unit[unit].texobj, tObj);
-               t->base.bound |= (1 << unit);
-               driUpdateTextureLRU(&t->base);  /* XXX: should be locked! */
+
+               if (t) {
+                       t->base.bound |= (1 << unit);
+                       driUpdateTextureLRU(&t->base);  /* XXX: should be locked! */
+               }
        }
 
-       return !t->border_fallback;
+       return !t || !t->border_fallback;
 }
 
 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
@@ -651,7 +657,7 @@ static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit)
        } else if (texUnit->_ReallyEnabled) {
                return GL_FALSE;
        } else {
-               return GL_TRUE;
+               return r300UpdateTexture(ctx, unit);
        }
 }