BGE: Fix T40555: LibLoad material caching issue

Previously we don't merge material cached list, it create dangling pointer and memory leak.
Now we merge material cache list during the scene merge, and remove material in this list during the library free.

Reviewers: agoose77, dfelinto, hg1, pgi, campbellbarton, moguri

Reviewed By: campbellbarton, moguri

Subscribers: campbellbarton, youle, kupoman

Projects: #game_engine

Differential Revision: https://developer.blender.org/D1278
This commit is contained in:
Porteries Tristan 2015-05-19 19:24:14 +02:00
parent fccf253e36
commit 377822729c
Notes: blender-bot 2023-02-14 11:01:33 +01:00
Referenced by issue #45267, Disabling 'Use Material Caching' causes Blender to crash when calling LibLoad
Referenced by issue #40924, LibNew & LibFree material bug
Referenced by issue #40555, Alternating LibLoad and LibFree crashes BGE
1 changed files with 15 additions and 1 deletions

View File

@ -903,7 +903,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
*err_str = err_local;
return NULL;
}
main_newlib = BKE_main_new();
BKE_reports_init(&reports, RPT_STORE);
@ -1218,6 +1218,8 @@ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
bmat = bl_mat->GetBlenderMaterial();
if (IS_TAGGED(bmat)) {
// Remove the poly material coresponding to this Blender Material.
m_polymat_cache[polymit->first].erase(bmat);
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
@ -1233,6 +1235,8 @@ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
for (i = 0, matit = m_materials.begin(); i < size; ) {
BL_Material *mat = (*matit).second;
if (IS_TAGGED(mat->material)) {
// Remove the bl material coresponding to this Blender Material.
m_mat_cache[matit->first].erase(mat->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
@ -1354,6 +1358,16 @@ bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
}
}
MaterialCache::iterator matcacheit = m_mat_cache.find(from);
// Merge cached BL_Material map.
m_mat_cache[to].insert(matcacheit->second.begin(), matcacheit->second.end());
m_mat_cache.erase(matcacheit);
PolyMaterialCache::iterator polymatcacheit = m_polymat_cache.find(from);
// Merge cached RAS_IPolyMaterial map.
m_polymat_cache[to].insert(polymatcacheit->second.begin(), polymatcacheit->second.end());
m_polymat_cache.erase(polymatcacheit);
return true;
}