BGE memleak fix: OpenGL Display Lists not deleted when switching scene

This fix also improves performance of Display List for replica objects: Display List ID caching is now enabled for replica objects which avoids a tree search on each frame and for each replica.
This commit is contained in:
Benoit Bolsee 2008-03-09 22:02:32 +00:00
parent 52293831b2
commit 1f0ae739cb
5 changed files with 63 additions and 11 deletions

@ -69,6 +69,11 @@ bool KX_MeshSlot::Less(const KX_MeshSlot& lhs) const
return result;
}
KX_MeshSlot::~KX_MeshSlot()
{
if (m_DisplayList)
m_DisplayList->Release();
}
RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)

@ -69,10 +69,21 @@ public:
*/
class KX_ListSlot
{
protected:
int m_refcount;
public:
KX_ListSlot(){}
virtual ~KX_ListSlot(){}
KX_ListSlot(){ m_refcount=1; }
virtual ~KX_ListSlot() {}
virtual int Release() {
if (--m_refcount > 0)
return m_refcount;
delete this;
return 0;
}
virtual KX_ListSlot* AddRef() {
m_refcount++;
return this;
}
virtual void SetModified(bool mod)=0;
};
@ -96,7 +107,7 @@ public:
m_DisplayList(0)
{
}
~KX_MeshSlot(){}
~KX_MeshSlot();
bool Less(const KX_MeshSlot& lhs) const;
};

@ -474,7 +474,9 @@ void RAS_MeshObject::ClearArrayData()
{
KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
if (ao)
{
delete *ao;
}
}
}

@ -25,13 +25,23 @@
#define spit(x)
//#endif
RAS_ListSlot::RAS_ListSlot()
RAS_ListSlot::RAS_ListSlot(RAS_ListRasterizer* rasty)
: KX_ListSlot(),
m_flag(LIST_MODIFY|LIST_CREATE),
m_list(0)
m_list(0),
m_rasty(rasty)
{
}
int RAS_ListSlot::Release()
{
if (--m_refcount > 0)
return m_refcount;
m_rasty->RemoveListSlot(this);
delete this;
return 0;
}
RAS_ListSlot::~RAS_ListSlot()
{
RemoveList();
@ -108,6 +118,18 @@ RAS_ListRasterizer::~RAS_ListRasterizer()
ReleaseAlloc();
}
void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list)
{
RAS_Lists::iterator it = mLists.begin();
while(it != mLists.end()) {
if (it->second == list) {
mLists.erase(it);
break;
}
it++;
}
}
RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(const vecVertexArray& vertexarrays, KX_ListSlot** slot)
{
/*
@ -120,10 +142,10 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(const vecVertexArray& vertexarrays,
if(!localSlot) {
RAS_Lists::iterator it = mLists.find(vertexarrays);
if(it == mLists.end()) {
localSlot = new RAS_ListSlot();
localSlot = new RAS_ListSlot(this);
mLists.insert(std::pair<vecVertexArray, RAS_ListSlot*>(vertexarrays, localSlot));
} else {
localSlot = it->second;
localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef());
}
}
MT_assert(localSlot);
@ -157,8 +179,12 @@ void RAS_ListRasterizer::IndexPrimitives(
if(!useObjectColor) {
localSlot = FindOrAdd(vertexarrays, slot);
localSlot->DrawList();
if(localSlot->End())
if(localSlot->End()) {
// save slot here too, needed for replicas and object using same mesh
// => they have the same vertexarray but different mesh slot
*slot = localSlot;
return;
}
}
if (mUseVertexArrays) {
@ -201,8 +227,12 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(
localSlot = FindOrAdd(vertexarrays, slot);
localSlot->DrawList();
if(localSlot->End())
if(localSlot->End()) {
// save slot here too, needed for replicas and object using same mesh
// => they have the same vertexarray but different mesh slot
*slot = localSlot;
return;
}
}
if (mUseVertexArrays) {

@ -5,14 +5,17 @@
#include "RAS_VAOpenGLRasterizer.h"
#include <vector>
class RAS_ListRasterizer;
class RAS_ListSlot : public KX_ListSlot
{
unsigned int m_list;
unsigned int m_flag;
RAS_ListRasterizer* m_rasty;
public:
RAS_ListSlot();
RAS_ListSlot(RAS_ListRasterizer* rasty);
virtual ~RAS_ListSlot();
virtual void SetModified(bool mod);
virtual int Release();
void RemoveList();
void DrawList();
@ -42,6 +45,7 @@ class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
void ReleaseAlloc();
public:
void RemoveListSlot(RAS_ListSlot* list);
RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays=false, bool lock=false);
virtual ~RAS_ListRasterizer();