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:
authorJeroen Bakker <jbakker>2021-11-10 15:50:00 +0300
committerJeroen Bakker <jeroen@blender.org>2021-11-10 15:50:15 +0300
commitbc0c06ecbe8cb23221e9cf05be6235e28d4597db (patch)
tree9f9ef2231d2f7e9a440dce9b7855547e08bc2461
parent47b8baa5c4e5b713d33e3925df9d55b882ae2a27 (diff)
Fix T91518: crash when recalculating looptris after clearing geometry.
When clearing geometry the runtime mutexes of a mesh were freed. This resulted in crashes afterwards. The clear geometry is an RNA function so would only effect when using from scripts. This patch separates init/freeing of the mutexes from other code so they can be used when needed. Reviewed By: mont29 Maniphest Tasks: T91518 Differential Revision: https://developer.blender.org/D13142
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h3
-rw-r--r--source/blender/blenkernel/intern/mesh.c8
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.c64
3 files changed, 53 insertions, 22 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index 3efbef94081..df111360bcd 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -41,7 +41,8 @@ struct Mesh;
struct Object;
struct Scene;
-void BKE_mesh_runtime_reset(struct Mesh *mesh);
+void BKE_mesh_runtime_init_data(struct Mesh *mesh);
+void BKE_mesh_runtime_free_data(struct Mesh *mesh);
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, const int flag);
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 7277f7ad209..f0ba83b396b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -88,7 +88,7 @@ static void mesh_init_data(ID *id)
CustomData_reset(&mesh->pdata);
CustomData_reset(&mesh->ldata);
- BKE_mesh_runtime_reset(mesh);
+ BKE_mesh_runtime_init_data(mesh);
mesh->face_sets_color_seed = BLI_hash_int(PIL_check_seconds_timer_i() & UINT_MAX);
}
@@ -168,7 +168,7 @@ static void mesh_free_data(ID *id)
mesh->edit_mesh = NULL;
}
- BKE_mesh_runtime_clear_cache(mesh);
+ BKE_mesh_runtime_free_data(mesh);
mesh_clear_geometry(mesh);
MEM_SAFE_FREE(mesh->mat);
}
@@ -308,7 +308,9 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
mesh->edit_mesh = NULL;
- BKE_mesh_runtime_reset(mesh);
+
+ memset(&mesh->runtime, 0, sizeof(mesh->runtime));
+ BKE_mesh_runtime_init_data(mesh);
/* happens with old files */
if (mesh->mselect == NULL) {
diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c
index 1c8646a4bdd..ce89c723a61 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.c
+++ b/source/blender/blenkernel/intern/mesh_runtime.c
@@ -45,17 +45,54 @@
* \{ */
/**
- * Default values defined at read time.
+ * \brief Initialize the runtime mutexes of the given mesh.
+ *
+ * Any existing mutexes will be overridden.
*/
-void BKE_mesh_runtime_reset(Mesh *mesh)
+static void mesh_runtime_init_mutexes(Mesh *mesh)
{
- memset(&mesh->runtime, 0, sizeof(mesh->runtime));
mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
BLI_mutex_init(mesh->runtime.eval_mutex);
mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
BLI_mutex_init(mesh->runtime.render_mutex);
}
+/**
+ * \brief free the mutexes of the given mesh runtime.
+ */
+static void mesh_runtime_free_mutexes(Mesh *mesh)
+{
+ if (mesh->runtime.eval_mutex != NULL) {
+ BLI_mutex_end(mesh->runtime.eval_mutex);
+ MEM_freeN(mesh->runtime.eval_mutex);
+ mesh->runtime.eval_mutex = NULL;
+ }
+ if (mesh->runtime.render_mutex != NULL) {
+ BLI_mutex_end(mesh->runtime.render_mutex);
+ MEM_freeN(mesh->runtime.render_mutex);
+ mesh->runtime.render_mutex = NULL;
+ }
+}
+
+/**
+ * \brief Initialize the runtime of the given mesh.
+ *
+ * Function expects that the runtime is already cleared.
+ */
+void BKE_mesh_runtime_init_data(Mesh *mesh)
+{
+ mesh_runtime_init_mutexes(mesh);
+}
+
+/**
+ * \brief Free all data (and mutexes) inside the runtime of the given mesh.
+ */
+void BKE_mesh_runtime_free_data(Mesh *mesh)
+{
+ BKE_mesh_runtime_clear_cache(mesh);
+ mesh_runtime_free_mutexes(mesh);
+}
+
/* Clear all pointers which we don't want to be shared on copying the datablock.
* However, keep all the flags which defines what the mesh is (for example, that
* it's deformed only, or that its custom data layers are out of date.) */
@@ -71,25 +108,16 @@ void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag))
runtime->bvh_cache = NULL;
runtime->shrinkwrap_data = NULL;
- mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
- BLI_mutex_init(mesh->runtime.eval_mutex);
-
- mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
- BLI_mutex_init(mesh->runtime.render_mutex);
+ mesh_runtime_init_mutexes(mesh);
}
+/**
+ * \brief This function clears runtime cache of the given mesh.
+ *
+ * Call this function to recalculate runtime data when used.
+ */
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
{
- if (mesh->runtime.eval_mutex != NULL) {
- BLI_mutex_end(mesh->runtime.eval_mutex);
- MEM_freeN(mesh->runtime.eval_mutex);
- mesh->runtime.eval_mutex = NULL;
- }
- if (mesh->runtime.render_mutex != NULL) {
- BLI_mutex_end(mesh->runtime.render_mutex);
- MEM_freeN(mesh->runtime.render_mutex);
- mesh->runtime.render_mutex = NULL;
- }
if (mesh->runtime.mesh_eval != NULL) {
mesh->runtime.mesh_eval->edit_mesh = NULL;
BKE_id_free(NULL, mesh->runtime.mesh_eval);