diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2009-05-23 18:46:43 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2009-05-23 18:46:43 +0400 |
commit | 5441323dca30c169d1ecb726d26e8cb4c5f4994d (patch) | |
tree | 1bcd7b2460f8980bacb03232498cdb7a02b9ba36 /source | |
parent | 6d8d7cd768f292a7fbbcecaf5f1cbc3090973f12 (diff) |
BGE: fix memleaks.
SCA_RandomActuator: The random generator was shared between replicas and not deleted. Added ref counting between replicas to allow deletion at the end.
KX_Camera: The scenegraph node was not deleted for temporary cameras (ImageMirror and shadow), causing 500 bytes leak per frame and per shadow light.
KX_GameActuator: Global dictionary buffer was not deleted after saving.
KX_MotionState: The motion state for compound child was not deleted
KX_ReplaceMeshActuator: The mesh was unnecessarily converted for each actuator and not deleted, causing large memleak.
After these fix, YoFrankie runs without memleak.
Diffstat (limited to 'source')
20 files changed, 85 insertions, 43 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index f3024197a8a..06a4da4fce0 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -729,6 +729,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* bool skinMesh = false; int lightlayer = blenderobj->lay; + if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL) + return meshobj; // Get DerivedMesh data DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj); @@ -1043,7 +1045,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* // pre calculate texture generation for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); mit != meshobj->GetLastMaterial(); ++ mit) { - mit->m_bucket->GetPolyMaterial()->OnConstruction(); + mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer); } if (layers) @@ -1057,6 +1059,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* delete kx_blmat; if (kx_polymat) delete kx_polymat; + converter->RegisterGameMesh(meshobj, mesh); return meshobj; } @@ -1712,14 +1715,9 @@ static KX_GameObject *gameobject_from_blenderobject( case OB_MESH: { Mesh* mesh = static_cast<Mesh*>(ob->data); - RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay); float center[3], extents[3]; float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents); - - if (!meshobj) { - meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter); - converter->RegisterGameMesh(meshobj, mesh); - } + RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter); // needed for python scripting kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index c9ac7a23625..646e569a27e 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -550,12 +550,12 @@ void KX_BlenderSceneConverter::RegisterGameMesh( RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh( - struct Mesh *for_blendermesh, - unsigned int onlayer) + struct Mesh *for_blendermesh/*, + unsigned int onlayer*/) { RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)]; - if (meshp && onlayer==(*meshp)->GetLightLayer()) { + if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) { return *meshp; } else { return NULL; diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h index 2317e952a0a..f7c1a506457 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.h +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h @@ -115,7 +115,7 @@ public: struct Object *FindBlenderObject(KX_GameObject *for_gameobject); void RegisterGameMesh(RAS_MeshObject *gamemesh, struct Mesh *for_blendermesh); - RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh, unsigned int onlayer); + RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh/*, unsigned int onlayer*/); // void RegisterSumoShape(DT_ShapeHandle shape, RAS_MeshObject *for_gamemesh); // DT_ShapeHandle FindSumoShape(RAS_MeshObject *for_gamemesh); diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp index 06b5cca6ce9..0267cc8ebbf 100644 --- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.cpp @@ -59,6 +59,7 @@ SCA_RandomNumberGenerator::SCA_RandomNumberGenerator(long seed) { // int mti = N + 1; /*unused*/ m_seed = seed; + m_refcount = 1; SetStartVector(); } diff --git a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h index b9311d31af6..842a0331752 100644 --- a/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h +++ b/source/gameengine/GameLogic/SCA_RandomNumberGenerator.h @@ -36,6 +36,9 @@ class SCA_RandomNumberGenerator { + /* reference counted for memleak */ + int m_refcount; + /** base seed */ long m_seed; @@ -56,6 +59,16 @@ class SCA_RandomNumberGenerator { float DrawFloat(); long GetSeed(); void SetSeed(long newseed); + SCA_RandomNumberGenerator* AddRef() + { + ++m_refcount; + return this; + } + void Release() + { + if (--m_refcount == 0) + delete this; + } }; #endif /* __KX_RANDOMNUMBERGENERATOR */ diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp index 3c04173d10e..d5cbeef01ae 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp +++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp @@ -50,7 +50,6 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, PyTypeObject* T) : SCA_ISensor(gameobj,eventmgr, T) { - // m_basegenerator is never deleted => memory leak m_basegenerator = new SCA_RandomNumberGenerator(startseed); Init(); } @@ -59,7 +58,7 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr, SCA_RandomSensor::~SCA_RandomSensor() { - /* Nothing to be done here. */ + m_basegenerator->Release(); } void SCA_RandomSensor::Init() @@ -74,13 +73,18 @@ void SCA_RandomSensor::Init() CValue* SCA_RandomSensor::GetReplica() { CValue* replica = new SCA_RandomSensor(*this); - // replication copies m_basegenerator pointer => share same generator // this will copy properties and so on... replica->ProcessReplica(); return replica; } +void SCA_RandomSensor::ProcessReplica() +{ + SCA_ISensor::ProcessReplica(); + // increment reference count so that we can release the generator at this end + m_basegenerator->AddRef(); +} bool SCA_RandomSensor::IsPositiveTrigger() diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index 27b41841f0b..b2bf2440966 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -52,6 +52,7 @@ public: PyTypeObject* T=&Type); virtual ~SCA_RandomSensor(); virtual CValue* GetReplica(); + virtual void ProcessReplica(); virtual bool Evaluate(); virtual bool IsPositiveTrigger(); virtual void Init(); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 3b8917efe90..f1543d752f1 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -158,14 +158,14 @@ void KX_BlenderMaterial::ReleaseMaterial() mBlenderShader->ReloadMaterial(); } -void KX_BlenderMaterial::OnConstruction() +void KX_BlenderMaterial::OnConstruction(int layer) { if (mConstructed) // when material are reused between objects return; if(mMaterial->glslmat) - SetBlenderGLSLShader(); + SetBlenderGLSLShader(layer); // for each unique material... int i; @@ -902,10 +902,10 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") } -void KX_BlenderMaterial::SetBlenderGLSLShader(void) +void KX_BlenderMaterial::SetBlenderGLSLShader(int layer) { if(!mBlenderShader) - mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer); + mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, layer); if(!mBlenderShader->Ok()) { delete mBlenderShader; diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 52019ed2248..b29f2df98db 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -97,7 +97,7 @@ public: // -------------------------------- // pre calculate to avoid pops/lag at startup - virtual void OnConstruction( ); + virtual void OnConstruction(int layer); static void EndFrame(); @@ -112,7 +112,7 @@ private: bool mModified; bool mConstructed; // if false, don't clean on exit - void SetBlenderGLSLShader(); + void SetBlenderGLSLShader(int layer); void ActivatGLMaterials( RAS_IRasterizer* rasty )const; void ActivateTexGen( RAS_IRasterizer *ras ) const; diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 4bef4936813..144ff4ac883 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -42,6 +42,7 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, SG_Callbacks callbacks, const RAS_CameraData& camdata, bool frustum_culling, + bool delete_node, PyTypeObject *T) : KX_GameObject(sgReplicationInfo,callbacks,T), @@ -50,7 +51,8 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, m_normalized(false), m_frustum_culling(frustum_culling), m_set_projection_matrix(false), - m_set_frustum_center(false) + m_set_frustum_center(false), + m_delete_node(delete_node) { // setting a name would be nice... m_name = "cam"; @@ -64,6 +66,12 @@ KX_Camera::KX_Camera(void* sgReplicationInfo, KX_Camera::~KX_Camera() { + if (m_delete_node && m_pSGNode) + { + // for shadow camera, avoids memleak + delete m_pSGNode; + m_pSGNode = NULL; + } } @@ -77,6 +85,13 @@ CValue* KX_Camera::GetReplica() return replica; } +void KX_Camera::ProcessReplica() +{ + KX_GameObject::ProcessReplica(); + // replicated camera are always registered in the scene + m_delete_node = false; +} + MT_Transform KX_Camera::GetWorldToCamera() const { MT_Transform camtrans; diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 2ec60be0404..aef21cd91e4 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -113,6 +113,11 @@ protected: bool m_set_frustum_center; /** + * whether the camera should delete the node itself (only for shadow camera) + */ + bool m_delete_node; + + /** * Extracts the camera clip frames from the projection and world-to-camera matrices. */ void ExtractClipPlanes(); @@ -138,7 +143,7 @@ public: enum { INSIDE, INTERSECT, OUTSIDE } ; - KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, PyTypeObject *T = &Type); + KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, bool delete_node = false, PyTypeObject *T = &Type); virtual ~KX_Camera(); /** @@ -149,6 +154,7 @@ public: virtual CValue* GetReplica( ); + virtual void ProcessReplica(); MT_Transform GetWorldToCamera() const; MT_Transform GetCameraToWorld() const; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index 406339586cc..76642649afc 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -980,6 +980,8 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, compoundShape->calculateLocalInertia(mass,localInertia); rigidbody->setMassProps(mass,localInertia); } + // delete motionstate as it's not used + delete motionstate; return; } diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp index 7c18b03906e..28bf12f5e87 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.cpp +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -149,6 +149,8 @@ bool KX_GameActuator::Update() } else { printf("Warning: could not create marshal buffer\n"); } + if (marshal_buffer) + delete [] marshal_buffer; } break; } diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 347634b4599..b30b79e7f23 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1142,7 +1142,7 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene) if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) { /* make temporary camera */ RAS_CameraData camdata = RAS_CameraData(); - KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false); + KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, true, true); cam->SetName("__shadow__cam__"); MT_Transform camtrans; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 98aad3943fe..506c167a905 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -220,7 +220,7 @@ PyAttributeDef KX_PolygonMaterial::Attributes[] = { KX_PYATTRIBUTE_INT_RW("tilexrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tilexrep), KX_PYATTRIBUTE_INT_RW("tileyrep", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_tileyrep), KX_PYATTRIBUTE_INT_RW("drawingmode", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_drawingmode), - KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer), + //KX_PYATTRIBUTE_INT_RW("lightlayer", INT_MIN, INT_MAX, true, KX_PolygonMaterial, m_lightlayer), KX_PYATTRIBUTE_BOOL_RW("transparent", KX_PolygonMaterial, m_alpha), KX_PYATTRIBUTE_BOOL_RW("zsort", KX_PolygonMaterial, m_zsort), diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index f2fd96d63e9..6af00d63c2d 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -59,7 +59,7 @@ void RAS_IPolyMaterial::Initialize( m_transp = transp; m_alpha = alpha; m_zsort = zsort; - m_lightlayer = lightlayer; + //m_lightlayer = lightlayer; m_polymatid = m_newpolymatid++; m_flag = 0; m_multimode = 0; @@ -80,7 +80,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial() m_transp(0), m_alpha(false), m_zsort(false), - m_lightlayer(0), + //m_lightlayer(0), m_polymatid(0), m_flag(0), m_multimode(0) @@ -112,7 +112,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, m_transp(transp), m_alpha(alpha), m_zsort(zsort), - m_lightlayer(lightlayer), + //m_lightlayer(lightlayer), m_polymatid(m_newpolymatid++), m_flag(0), m_multimode(0) @@ -172,10 +172,10 @@ bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const return m_polymatid < rhs.m_polymatid; } -int RAS_IPolyMaterial::GetLightLayer() const -{ - return m_lightlayer; -} +//int RAS_IPolyMaterial::GetLightLayer() const +//{ +// return m_lightlayer; +//} bool RAS_IPolyMaterial::IsAlpha() const { diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index decd93c3d13..e19db35ccb5 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -73,7 +73,7 @@ protected: int m_transp; bool m_alpha; bool m_zsort; - int m_lightlayer; + //int m_lightlayer; int m_materialindex; unsigned int m_polymatid; @@ -147,7 +147,7 @@ public: virtual bool Equals(const RAS_IPolyMaterial& lhs) const; bool Less(const RAS_IPolyMaterial& rhs) const; - int GetLightLayer() const; + //int GetLightLayer() const; bool IsAlpha() const; bool IsZSort() const; unsigned int hash() const; @@ -167,7 +167,7 @@ public: /* * PreCalculate texture gen */ - virtual void OnConstruction(){} + virtual void OnConstruction(int layer){} }; inline bool operator ==( const RAS_IPolyMaterial & rhs,const RAS_IPolyMaterial & lhs) diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp index edd7615efd4..1cb394aaff3 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp +++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp @@ -91,7 +91,7 @@ struct RAS_MeshObject::fronttoback STR_String RAS_MeshObject::s_emptyname = ""; RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer) - : m_lightlayer(lightlayer), + : //m_lightlayer(lightlayer), m_bModified(true), m_bMeshModified(true), m_mesh(mesh), @@ -112,10 +112,10 @@ bool RAS_MeshObject::MeshModified() return m_bMeshModified; } -unsigned int RAS_MeshObject::GetLightLayer() -{ - return m_lightlayer; -} +//unsigned int RAS_MeshObject::GetLightLayer() +//{ +// return m_lightlayer; +//} diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h index fbc3c549a7a..0a16c7fa0f6 100644 --- a/source/gameengine/Rasterizer/RAS_MeshObject.h +++ b/source/gameengine/Rasterizer/RAS_MeshObject.h @@ -54,7 +54,7 @@ class RAS_MeshObject { private: unsigned int m_debugcolor; - int m_lightlayer; + //int m_lightlayer; bool m_bModified; bool m_bMeshModified; @@ -94,7 +94,7 @@ public: list<RAS_MeshMaterial>::iterator GetFirstMaterial(); list<RAS_MeshMaterial>::iterator GetLastMaterial(); - unsigned int GetLightLayer(); + //unsigned int GetLightLayer(); /* name */ void SetName(const char *name); diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index db4461325d8..7ceb9e58c7a 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -561,8 +561,8 @@ ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObj float yaxis[3] = {0.f, 1.f, 0.f}; float mirrorMat[3][3]; float left, right, top, bottom, back; - - m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata); + // make sure this camera will delete its node + m_camera= new KX_Camera(scene, KX_Scene::m_callbacks, camdata, true, true); m_camera->SetName("__mirror__cam__"); // don't add the camera to the scene object list, it doesn't need to be accessible m_owncamera = true; |