From 0ddce08c9413c10105bb71450cd96ee622df3b49 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 24 Apr 2020 22:00:23 +0200 Subject: [PATCH] fixed a memory leak --- src/clump.cpp | 2 +- src/geometry.cpp | 11 +++++------ src/matfx.cpp | 14 +++++++------- src/rwobjects.h | 6 ++++++ src/texture.cpp | 31 +++++++++++++++++++++++++++---- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/clump.cpp b/src/clump.cpp index 974b4c0..8ccc990 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -480,7 +480,7 @@ Atomic::setGeometry(Geometry *geo, uint32 flags) if(this->geometry) this->geometry->destroy(); if(geo) - geo->refCount++; + geo->addRef(); this->geometry = geo; if(flags & SAMEBOUNDINGSPHERE) return; diff --git a/src/geometry.cpp b/src/geometry.cpp index 5a993f1..12dc4ee 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -641,7 +641,7 @@ Geometry::removeUnusedMaterials(void) if(m[i].numIndices <= 0) continue; materials[numMaterials] = m[i].material; - m[i].material->refCount++; + m[i].material->addRef(); int32 oldid = this->matList.findIndex(m[i].material); map[oldid] = numMaterials; numMaterials++; @@ -748,7 +748,7 @@ MaterialList::appendMaterial(Material *mat) this->materials = ml; } this->materials[this->numMaterials++] = mat; - mat->refCount++; + mat->addRef(); return this->numMaterials-1; } @@ -786,7 +786,7 @@ MaterialList::streamRead(Stream *stream, MaterialList *matlist) for(int32 i = 0; i < numMat; i++){ if(indices[i] >= 0){ m = matlist->materials[indices[i]]; - m->refCount++; + m->addRef(); }else{ if(!findChunk(stream, ID_MATERIAL, nil, nil)){ RWERROR((ERR_CHUNK, "MATERIAL")); @@ -907,7 +907,7 @@ Material::setTexture(Texture *tex) if(this->texture) this->texture->destroy(); if(tex) - tex->refCount++; + tex->addRef(); this->texture = tex; } @@ -945,8 +945,7 @@ Material::streamRead(Stream *stream) RWERROR((ERR_CHUNK, "TEXTURE")); goto fail; } - Texture *t = Texture::streamRead(stream); - mat->setTexture(t); + mat->texture = Texture::streamRead(stream); } materialRights[0] = 0; diff --git a/src/matfx.cpp b/src/matfx.cpp index 919d0b9..f9c2792 100644 --- a/src/matfx.cpp +++ b/src/matfx.cpp @@ -166,7 +166,7 @@ MatFX::setBumpTexture(Texture *t) this->fx[i].bump.tex->destroy(); this->fx[i].bump.tex = t; if(t) - t->refCount++; + t->addRef(); } } @@ -205,7 +205,7 @@ MatFX::setEnvTexture(Texture *t) this->fx[i].env.tex->destroy(); this->fx[i].env.tex = t; if(t) - t->refCount++; + t->addRef(); } } @@ -262,7 +262,7 @@ MatFX::setDualTexture(Texture *t) this->fx[i].dual.tex->destroy(); this->fx[i].dual.tex = t; if(t) - t->refCount++; + t->addRef(); } } @@ -363,19 +363,19 @@ copyMaterialMatFX(void *dst, void *src, int32 offset, int32) switch(dstfx->fx[i].type){ case MatFX::BUMPMAP: if(dstfx->fx[i].bump.bumpedTex) - dstfx->fx[i].bump.bumpedTex->refCount++; + dstfx->fx[i].bump.bumpedTex->addRef(); if(dstfx->fx[i].bump.tex) - dstfx->fx[i].bump.tex->refCount++; + dstfx->fx[i].bump.tex->addRef(); break; case MatFX::ENVMAP: if(dstfx->fx[i].env.tex) - dstfx->fx[i].env.tex->refCount++; + dstfx->fx[i].env.tex->addRef(); break; case MatFX::DUAL: if(dstfx->fx[i].dual.tex) - dstfx->fx[i].dual.tex->refCount++; + dstfx->fx[i].dual.tex->addRef(); break; } return dst; diff --git a/src/rwobjects.h b/src/rwobjects.h index 75dc02e..8a33cc8 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -282,9 +282,12 @@ struct Texture uint32 filterAddressing; // VVVVUUUU FFFFFFFF int32 refCount; + LLLink inGlobalList; // actually not in RW + static int32 numAllocated; static Texture *create(Raster *raster); + void addRef(void) { this->refCount++; } void destroy(void); static Texture *fromDict(LLLink *lnk){ return LLLinkGetData(lnk, Texture, inDict); } @@ -332,6 +335,7 @@ struct Material static int32 numAllocated; static Material *create(void); + void addRef(void) { this->refCount++; } Material *clone(void); void destroy(void); void setTexture(Texture *tex); @@ -431,6 +435,7 @@ struct Geometry static int32 numAllocated; static Geometry *create(int32 numVerts, int32 numTris, uint32 flags); + void addRef(void) { this->refCount++; } void destroy(void); void lock(int32 lockFlags); void unlock(void); @@ -785,6 +790,7 @@ struct TexDictionary int32 count(void) { return this->textures.count(); } void add(Texture *t); void addFront(Texture *t); + void remove(Texture *t); Texture *find(const char *name); static TexDictionary *streamRead(Stream *stream); void streamWrite(Stream *stream); diff --git a/src/texture.cpp b/src/texture.cpp index d99c366..6e89239 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -35,6 +35,8 @@ struct TextureGlobals // create dummy textures to store just names bool32 makeDummies; LinkList texDicts; + + LinkList textures; }; int32 textureModuleOffset; @@ -46,6 +48,7 @@ textureOpen(void *object, int32 offset, int32 size) TexDictionary *texdict; textureModuleOffset = offset; TEXTUREGLOBAL(texDicts).init(); + TEXTUREGLOBAL(textures).init(); texdict = TexDictionary::create(); TEXTUREGLOBAL(initialTexDict) = texdict; TexDictionary::setCurrent(texdict); @@ -60,6 +63,13 @@ textureClose(void *object, int32 offset, int32 size) TexDictionary::fromLink(lnk)->destroy(); TEXTUREGLOBAL(initialTexDict) = nil; TEXTUREGLOBAL(currentTexDict) = nil; + + FORLIST(lnk, TEXTUREGLOBAL(textures)){ + Texture *tex = LLLinkGetData(lnk, Texture, inGlobalList); + printf("Tex still allocated: %d %s %s\n", tex->refCount, tex->name, tex->mask); + assert(tex->dict == nil); + tex->destroy(); + } return object; } @@ -106,10 +116,13 @@ TexDictionary::destroy(void) { if(TEXTUREGLOBAL(currentTexDict) == this) TEXTUREGLOBAL(currentTexDict) = nil; - FORLIST(lnk, this->textures) - Texture::fromDict(lnk)->destroy(); - this->inGlobalList.remove(); + FORLIST(lnk, this->textures){ + Texture *tex = Texture::fromDict(lnk); + this->remove(tex); + tex->destroy(); + } s_plglist.destruct(this); + this->inGlobalList.remove(); rwFree(this); numAllocated--; } @@ -123,6 +136,14 @@ TexDictionary::add(Texture *t) this->textures.append(&t->inDict); } +void +TexDictionary::remove(Texture *t) +{ + assert(t->dict == this); + t->inDict.remove(); + t->dict = nil; +} + void TexDictionary::addFront(Texture *t) { @@ -246,6 +267,7 @@ Texture::create(Raster *raster) tex->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST; tex->raster = raster; tex->refCount = 1; + TEXTUREGLOBAL(textures).add(&tex->inGlobalList); s_plglist.construct(tex); return tex; } @@ -260,6 +282,7 @@ Texture::destroy(void) this->inDict.remove(); if(this->raster) this->raster->destroy(); + this->inGlobalList.remove(); rwFree(this); numAllocated--; } @@ -311,7 +334,7 @@ Texture::read(const char *name, const char *mask) Texture *tex; if(tex = Texture::findCB(name), tex){ - tex->refCount++; + tex->addRef(); return tex; } if(TEXTUREGLOBAL(loadTextures)){