Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Converter/KX_BlenderSceneConverter.cpp')
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp101
1 files changed, 59 insertions, 42 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 9d01d3d5a39..b97d0b2a85d 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -108,12 +108,12 @@ extern "C" {
#include "../../blender/blenlib/BLI_linklist.h"
}
-#include <pthread.h>
+#include "BLI_task.h"
-/* This is used to avoid including pthread.h in KX_BlenderSceneConverter.h */
+// This is used to avoid including BLI_task.h in KX_BlenderSceneConverter.h
typedef struct ThreadInfo {
- vector<pthread_t> threads;
- pthread_mutex_t merge_lock;
+ TaskPool *m_pool;
+ ThreadMutex m_mutex;
} ThreadInfo;
KX_BlenderSceneConverter::KX_BlenderSceneConverter(
@@ -126,10 +126,11 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter(
m_useglslmat(false),
m_use_mat_cache(true)
{
- BKE_main_id_tag_all(maggie, false); /* avoid re-tagging later on */
+ BKE_main_id_tag_all(maggie, LIB_TAG_DOIT, false); /* avoid re-tagging later on */
m_newfilename = "";
m_threadinfo = new ThreadInfo();
- pthread_mutex_init(&m_threadinfo->merge_lock, NULL);
+ m_threadinfo->m_pool = BLI_task_pool_create(engine->GetTaskScheduler(), NULL);
+ BLI_mutex_init(&m_threadinfo->m_mutex);
}
KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
@@ -137,17 +138,6 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
// clears meshes, and hashmaps from blender to gameengine data
// delete sumoshapes
- if (m_threadinfo) {
- vector<pthread_t>::iterator pit = m_threadinfo->threads.begin();
- while (pit != m_threadinfo->threads.end()) {
- pthread_join((*pit), NULL);
- pit++;
- }
-
- pthread_mutex_destroy(&m_threadinfo->merge_lock);
- delete m_threadinfo;
- }
-
int numAdtLists = m_map_blender_to_gameAdtList.size();
for (int i = 0; i < numAdtLists; i++) {
BL_InterpolatorList *adtList = *m_map_blender_to_gameAdtList.at(i);
@@ -190,6 +180,15 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
}
m_DynamicMaggie.clear();
+
+ if (m_threadinfo) {
+ /* Thread infos like mutex must be freed after FreeBlendFile function.
+ Because it needs to lock the mutex, even if there's no active task when it's
+ in the scene converter destructor. */
+ BLI_task_pool_free(m_threadinfo->m_pool);
+ BLI_mutex_end(&m_threadinfo->m_mutex);
+ delete m_threadinfo;
+ }
}
void KX_BlenderSceneConverter::SetNewFileName(const STR_String &filename)
@@ -631,8 +630,8 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat);
- insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "location", -1, (float)frameNumber, INSERTKEY_FAST);
- insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "rotation_euler", -1, (float)frameNumber, INSERTKEY_FAST);
+ insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "location", -1, (float)frameNumber, BEZT_KEYTYPE_JITTER, INSERTKEY_FAST);
+ insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "rotation_euler", -1, (float)frameNumber, BEZT_KEYTYPE_JITTER, INSERTKEY_FAST);
#if 0
const MT_Point3& position = gameObj->NodeGetWorldPosition();
@@ -787,7 +786,7 @@ void KX_BlenderSceneConverter::MergeAsyncLoads()
vector<KX_LibLoadStatus *>::iterator mit;
vector<KX_Scene *>::iterator sit;
- pthread_mutex_lock(&m_threadinfo->merge_lock);
+ BLI_mutex_lock(&m_threadinfo->m_mutex);
for (mit = m_mergequeue.begin(); mit != m_mergequeue.end(); ++mit) {
merge_scenes = (vector<KX_Scene *> *)(*mit)->GetData();
@@ -805,17 +804,27 @@ void KX_BlenderSceneConverter::MergeAsyncLoads()
m_mergequeue.clear();
- pthread_mutex_unlock(&m_threadinfo->merge_lock);
+ BLI_mutex_unlock(&m_threadinfo->m_mutex);
+}
+
+void KX_BlenderSceneConverter::FinalizeAsyncLoads()
+{
+ // Finish all loading libraries.
+ if (m_threadinfo) {
+ BLI_task_pool_work_and_wait(m_threadinfo->m_pool);
+ }
+ // Merge all libraries data in the current scene, to avoid memory leak of unmerged scenes.
+ MergeAsyncLoads();
}
void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status)
{
- pthread_mutex_lock(&m_threadinfo->merge_lock);
+ BLI_mutex_lock(&m_threadinfo->m_mutex);
m_mergequeue.push_back(status);
- pthread_mutex_unlock(&m_threadinfo->merge_lock);
+ BLI_mutex_unlock(&m_threadinfo->m_mutex);
}
-static void *async_convert(void *ptr)
+static void async_convert(TaskPool *pool, void *ptr, int UNUSED(threadid))
{
KX_Scene *new_scene = NULL;
KX_LibLoadStatus *status = (KX_LibLoadStatus *)ptr;
@@ -835,8 +844,6 @@ static void *async_convert(void *ptr)
status->SetData(merge_scenes);
status->GetConverter()->AddScenesToMergeQueue(status);
-
- return NULL;
}
KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
@@ -865,7 +872,7 @@ static void load_datablocks(Main *main_tmp, BlendHandle *bpy_openlib, const char
int i = 0;
LinkNode *n = names;
while (n) {
- BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode);
+ BLO_library_link_named_part(main_tmp, &bpy_openlib, idcode, (char *)n->link);
n = (LinkNode *)n->next;
i++;
}
@@ -909,7 +916,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
short flag = 0; /* don't need any special options */
/* created only for linking, then freed */
- Main *main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path);
+ Main *main_tmp = BLO_library_link_begin(main_newlib, &bpy_openlib, (char *)path);
load_datablocks(main_tmp, bpy_openlib, path, idcode);
@@ -922,7 +929,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
load_datablocks(main_tmp, bpy_openlib, path, ID_AC);
}
- BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
+ BLO_library_link_end(main_tmp, &bpy_openlib, flag, NULL, NULL);
BLO_blendhandle_close(bpy_openlib);
@@ -981,10 +988,8 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
}
if (options & LIB_LOAD_ASYNC) {
- pthread_t id;
status->SetData(scenes);
- pthread_create(&id, NULL, &async_convert, (void *)status);
- m_threadinfo->threads.push_back(id);
+ BLI_task_pool_push(m_threadinfo->m_pool, async_convert, (void *)status, false, TASK_PRIORITY_LOW);
}
#ifdef WITH_PYTHON
@@ -1023,12 +1028,24 @@ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
if (maggie == NULL)
return false;
-
+
+ // If the given library is currently in loading, we do nothing.
+ if (m_status_map.count(maggie->name)) {
+ BLI_mutex_lock(&m_threadinfo->m_mutex);
+ const bool finished = m_status_map[maggie->name]->IsFinished();
+ BLI_mutex_unlock(&m_threadinfo->m_mutex);
+
+ if (!finished) {
+ printf("Library (%s) is currently being loaded asynchronously, and cannot be freed until this process is done\n", maggie->name);
+ return false;
+ }
+ }
+
/* tag all false except the one we remove */
for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) {
Main *main = *it;
if (main != maggie) {
- BKE_main_id_tag_all(main, false);
+ BKE_main_id_tag_all(main, LIB_TAG_DOIT, false);
}
else {
maggie_index = i;
@@ -1041,7 +1058,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
return false;
m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index);
- BKE_main_id_tag_all(maggie, true);
+ BKE_main_id_tag_all(maggie, LIB_TAG_DOIT, true);
/* free all tagged objects */
KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
@@ -1409,7 +1426,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene *kx_scene,
printf("Mesh has a user \"%s\"\n", name);
#endif
me = (ID*)BKE_mesh_copy_ex(from_maggie, (Mesh*)me);
- me->us--;
+ id_us_min(me);
}
BLI_remlink(&from_maggie->mesh, me); /* even if we made the copy it needs to be removed */
BLI_addtail(&maggie->mesh, me);
@@ -1421,19 +1438,19 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene *kx_scene,
/* ensure all materials are tagged */
for (int i = 0; i < mesh->totcol; i++) {
if (mesh->mat[i])
- mesh->mat[i]->id.flag &= ~LIB_DOIT;
+ mesh->mat[i]->id.tag &= ~LIB_TAG_DOIT;
}
for (int i = 0; i < mesh->totcol; i++) {
Material *mat_old = mesh->mat[i];
/* if its tagged its a replaced material */
- if (mat_old && (mat_old->id.flag & LIB_DOIT) == 0) {
+ if (mat_old && (mat_old->id.tag & LIB_TAG_DOIT) == 0) {
Material *mat_old = mesh->mat[i];
Material *mat_new = BKE_material_copy(mat_old);
- mat_new->id.flag |= LIB_DOIT;
- mat_old->id.us--;
+ mat_new->id.tag |= LIB_TAG_DOIT;
+ id_us_min(&mat_old->id);
BLI_remlink(&G.main->mat, mat_new); // BKE_material_copy uses G.main, and there is no BKE_material_copy_ex
BLI_addtail(&maggie->mat, mat_new);
@@ -1444,8 +1461,8 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene *kx_scene,
for (int j = i + 1; j < mesh->totcol; j++) {
if (mesh->mat[j] == mat_old) {
mesh->mat[j] = mat_new;
- mat_new->id.us++;
- mat_old->id.us--;
+ id_us_plus(&mat_new->id);
+ id_us_min(&mat_old->id);
}
}
}