Plug the memory/texture/vbo leaks.

QF still leaks about 3MB/run on demo1, but even 100 runs didn't show any
render issues.
This commit is contained in:
Bill Currie 2012-01-29 22:32:35 +09:00
parent b03e937b67
commit 497718cc40
8 changed files with 98 additions and 8 deletions

View file

@ -422,6 +422,7 @@ typedef struct model_s {
// additional model data
cache_user_t cache;
void (*clear) (struct model_s *m);
} model_t;
// ============================================================================

View file

@ -58,6 +58,42 @@ static vec3_t vertex_normals[NUMVERTEXNORMALS] = {
#include "anorms.h"
};
static void
glsl_alias_clear (model_t *m)
{
int i, j;
aliashdr_t *hdr;
GLuint bufs[2];
maliasskindesc_t *skins;
maliasskingroup_t *group;
m->needload = true;
if (!(hdr = m->aliashdr))
hdr = Cache_Get (&m->cache);
bufs[0] = hdr->posedata;
bufs[1] = hdr->commands;
qfglDeleteBuffers (2, bufs);
skins = ((maliasskindesc_t *) ((byte *) hdr + hdr->skindesc));
for (i = 0; i < hdr->mdl.numskins; i++) {
if (skins[i].type == ALIAS_SKIN_GROUP) {
group = (maliasskingroup_t *) ((byte *) hdr + skins[i].skin);
for (j = 0; j < group->numskins; j++) {
GL_ReleaseTexture (group->skindescs[j].texnum);
}
} else {
GL_ReleaseTexture (skins[i].texnum);
}
}
if (!m->aliashdr) {
Cache_Release (&m->cache);
Cache_Free (&m->cache);
}
}
void *
Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc)
@ -85,6 +121,7 @@ Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr)
{
if (hdr->mdl.ident == HEADER_MDL16)
VectorScale (hdr->mdl.scale, 1/256.0, hdr->mdl.scale);
m->clear = glsl_alias_clear;
}
void

View file

@ -58,6 +58,26 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
#include "compat.h"
static void
glsl_brush_clear (model_t *m)
{
int i;
m->needload = true;
for (i = 0; i < m->numtextures; i++) {
if (m->textures[i]->gl_texturenum) {
GL_ReleaseTexture (m->textures[i]->gl_texturenum);
m->textures[i]->gl_texturenum = 0;
}
}
for (i = 0; i < m->numsurfaces; i++) {
if (m->surfaces[i].polys) {
free (m->surfaces[i].polys);
m->surfaces[i].polys = 0;
}
}
}
void
Mod_ProcessTexture (texture_t *tx)
{
@ -95,6 +115,8 @@ Mod_LoadExternalTextures (model_t *mod)
void
Mod_LoadLighting (bsp_t *bsp)
{
// a big hacky, but it's as good a place as any
loadmodel->clear = glsl_brush_clear;
mod_lightmap_bytes = 1;
if (!bsp->lightdatasize) {
loadmodel->lightdata = NULL;

View file

@ -912,6 +912,8 @@ Mod_LoadBrushModel (model_t *mod, void *buffer)
Mod_LoadEntities (bsp);
Mod_LoadSubmodels (bsp);
BSP_Free(bsp);
Mod_MakeHull0 ();
mod->numframes = 2; // regular and alternate animation

View file

@ -120,10 +120,14 @@ Mod_ClearAll (void)
model_t **mod;
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) {
if ((*mod)->type != mod_alias)
(*mod)->needload = true;
if ((*mod)->type == mod_sprite)
(*mod)->cache.data = 0;
if (!(*mod)->needload && (*mod)->clear) {
(*mod)->clear (*mod);
} else {
if ((*mod)->type != mod_alias)
(*mod)->needload = true;
if ((*mod)->type == mod_sprite)
(*mod)->cache.data = 0;
}
}
}
@ -237,7 +241,7 @@ static model_t *
Mod_LoadModel (model_t *mod, qboolean crash)
{
if (!mod->needload) {
if (mod->type == mod_alias) {
if (mod->type == mod_alias && !mod->aliashdr) {
if (Cache_Check (&mod->cache))
return mod;
} else

View file

@ -31,8 +31,7 @@
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id$";
static __attribute__ ((used)) const char rcsid[] = "$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
@ -49,11 +48,36 @@ static __attribute__ ((used)) const char rcsid[] =
#include "compat.h"
static void
glsl_sprite_clear (model_t *m)
{
int i, j;
msprite_t *sprite = (msprite_t *) m->cache.data;
mspritegroup_t *group;
mspriteframe_t *frame;
m->needload = true;
m->cache.data = 0;
for (i = 0; i < sprite->numframes; i++) {
if (sprite->frames[i].type == SPR_SINGLE) {
frame = sprite->frames[i].frameptr;
GL_ReleaseTexture (frame->gl_texturenum);
} else {
group = (mspritegroup_t *) sprite->frames[i].frameptr;
for (j = 0; j < group->numframes; j++) {
frame = group->frames[j];
GL_ReleaseTexture (frame->gl_texturenum);
}
}
}
}
void
Mod_SpriteLoadTexture (mspriteframe_t *pspriteframe, int framenum)
{
const char *name;
loadmodel->clear = glsl_sprite_clear;
name = va ("%s_%i", loadmodel->name, framenum);
pspriteframe->gl_texturenum =
GL_LoadQuakeTexture (name, pspriteframe->width, pspriteframe->height,

View file

@ -466,7 +466,6 @@ build_surf_displist (model_t **models, msurface_t *fa, int base,
numtris = numverts - 2;
numindices = numtris * 3;
verts = alloca (numverts * sizeof (bspvert_t));
//FIXME leak
poly = malloc (field_offset (glslpoly_t, indices[numindices]));
poly->count = numindices;
for (i = 0, ind = poly->indices; i < numtris; i++) {

View file

@ -313,6 +313,7 @@ dump_program (const char *name, int program)
Sys_Printf ("Attribute %i name \"%s\" size %i type %s\n", (int)ind,
pname->str, (int)psize, type_name (ptype));
}
dstring_delete (pname);
}
int