From 1a5c42810009e072fd06773b812535591682bc98 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Mon, 26 Jan 2015 20:18:39 +0000 Subject: [PATCH] VID_Restart: delete all GL textures before calling VID_SetMode. SDL2 reuses the gl context when changing modes, so the TexMgr_ReloadImages call after the mode change was leaking textures. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1156 af15c1b1-3010-417e-b628-4374ebc0bcbd --- Quake/gl_texmgr.c | 41 +++++++++++++++++++++++++++++++++++++++-- Quake/gl_texmgr.h | 1 + Quake/gl_vidsdl.c | 7 +++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Quake/gl_texmgr.c b/Quake/gl_texmgr.c index 492c037b..f92af8cb 100644 --- a/Quake/gl_texmgr.c +++ b/Quake/gl_texmgr.c @@ -341,6 +341,8 @@ gltexture_t *TexMgr_NewTexture (void) return glt; } +static void GL_DeleteTexture (gltexture_t *texture); + /* ================ TexMgr_FreeTexture @@ -362,7 +364,7 @@ void TexMgr_FreeTexture (gltexture_t *kill) kill->next = free_gltextures; free_gltextures = kill; - glDeleteTextures(1, &kill->texnum); + GL_DeleteTexture(kill); numgltextures--; return; } @@ -375,7 +377,7 @@ void TexMgr_FreeTexture (gltexture_t *kill) kill->next = free_gltextures; free_gltextures = kill; - glDeleteTextures(1, &kill->texnum); + GL_DeleteTexture(kill); numgltextures--; return; } @@ -420,6 +422,21 @@ void TexMgr_FreeTexturesForOwner (qmodel_t *owner) } } +/* +================ +TexMgr_DeleteTextureObjects +================ +*/ +void TexMgr_DeleteTextureObjects (void) +{ + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + { + GL_DeleteTexture (glt); + } +} + /* ================================================================================ @@ -1466,3 +1483,23 @@ void GL_Bind (gltexture_t *texture) texture->visframe = r_framecount; } } + +/* +================ +GL_DeleteTexture -- ericw + +Wrapper around glDeleteTextures that also updates our cached current texture +binding, if necessary. +================ +*/ +static void GL_DeleteTexture (gltexture_t *texture) +{ + glDeleteTextures (1, &texture->texnum); + + if (texture->texnum == currenttexture[currenttarget - GL_TEXTURE0_ARB]) + { + currenttexture[currenttarget - GL_TEXTURE0_ARB] = 0; + } + + texture->texnum = 0; +} diff --git a/Quake/gl_texmgr.h b/Quake/gl_texmgr.h index 472d7342..f772df30 100644 --- a/Quake/gl_texmgr.h +++ b/Quake/gl_texmgr.h @@ -85,6 +85,7 @@ void TexMgr_FreeTextures (unsigned int flags, unsigned int mask); void TexMgr_FreeTexturesForOwner (qmodel_t *owner); void TexMgr_NewGame (void); void TexMgr_Init (void); +void TexMgr_DeleteTextureObjects (void); // IMAGE LOADING gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format, diff --git a/Quake/gl_vidsdl.c b/Quake/gl_vidsdl.c index 37627cdd..c0c7ff4e 100644 --- a/Quake/gl_vidsdl.c +++ b/Quake/gl_vidsdl.c @@ -676,6 +676,13 @@ static void VID_Restart (void) width, height, bpp, fullscreen? "fullscreen" : "windowed"); return; } + +// ericw -- depending on platform / SDL version, after a video mode change we +// can have a new context (all textures are already freed) or the same context +// as before, in which case we need to delete the old textures to avoid a +// memory leak. + + TexMgr_DeleteTextureObjects (); // // set new mode