diff options
author | Mitchell Stokes <mogurijin@gmail.com> | 2014-05-15 06:11:08 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2014-05-15 06:11:08 +0400 |
commit | ff2ec0566208a3594ef46577062a97119cfe9b2c (patch) | |
tree | 4d05959d2421668e7334fe39cc805e9640666dea | |
parent | 064ef3f00f286a5bb4b17c83cc8246c0ef0b123d (diff) |
Fix T40199: bge.logic.LibFree() could cause crashes by leaving dangling pointers in the rasterizer.
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.cpp | 35 | ||||
-rw-r--r-- | source/gameengine/Rasterizer/RAS_BucketManager.h | 2 |
2 files changed, 36 insertions, 1 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 7d7f8ebd4b3..88fd10b4547 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -1382,10 +1382,42 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) } vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit; + RAS_BucketManager::BucketList::iterator bit; + list<RAS_MeshSlot>::iterator msit; + RAS_BucketManager::BucketList buckets; + size = m_meshobjects.size(); for (i=0, meshit=m_meshobjects.begin(); i<size; ) { RAS_MeshObject *me= (*meshit).second; if (IS_TAGGED(me->GetMesh())) { + // Before deleting the mesh object, make sure the rasterizer is + // no longer referencing it. + buckets = meshit->first->GetBucketManager()->GetSolidBuckets(); + for (bit=buckets.begin(); bit!=buckets.end(); bit++) { + msit = (*bit)->msBegin(); + + while (msit != (*bit)->msEnd()) { + if (msit->m_mesh == meshit->second) + (*bit)->RemoveMesh(&(*msit++)); + else + msit++; + } + } + + // And now the alpha buckets + buckets = meshit->first->GetBucketManager()->GetAlphaBuckets(); + for (bit=buckets.begin(); bit!=buckets.end(); bit++) { + msit = (*bit)->msBegin(); + + while (msit != (*bit)->msEnd()) { + if (msit->m_mesh == meshit->second) + (*bit)->RemoveMesh(&(*msit++)); + else + msit++; + } + } + + // Now it should be safe to delete delete (*meshit).second; *meshit = m_meshobjects.back(); m_meshobjects.pop_back(); @@ -1536,7 +1568,8 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, } } } - + + m_currentScene = kx_scene; // This needs to be set in case we LibLoaded earlier RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false); kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */ diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index f8c6375d474..5ed212ebee0 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -39,7 +39,9 @@ class RAS_BucketManager { +public: typedef std::vector<class RAS_MaterialBucket*> BucketList; +private: BucketList m_SolidBuckets; BucketList m_AlphaBuckets; |