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
This commit is contained in:
parent
47b8baa5c4
commit
bc0c06ecbe
|
@ -41,7 +41,8 @@ struct Mesh;
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Scene;
|
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);
|
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, const int flag);
|
||||||
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
|
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
|
||||||
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
|
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
|
||||||
|
|
|
@ -88,7 +88,7 @@ static void mesh_init_data(ID *id)
|
||||||
CustomData_reset(&mesh->pdata);
|
CustomData_reset(&mesh->pdata);
|
||||||
CustomData_reset(&mesh->ldata);
|
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);
|
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;
|
mesh->edit_mesh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BKE_mesh_runtime_clear_cache(mesh);
|
BKE_mesh_runtime_free_data(mesh);
|
||||||
mesh_clear_geometry(mesh);
|
mesh_clear_geometry(mesh);
|
||||||
MEM_SAFE_FREE(mesh->mat);
|
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->texflag &= ~ME_AUTOSPACE_EVALUATED;
|
||||||
mesh->edit_mesh = NULL;
|
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 */
|
/* happens with old files */
|
||||||
if (mesh->mselect == NULL) {
|
if (mesh->mselect == NULL) {
|
||||||
|
|
|
@ -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");
|
mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
|
||||||
BLI_mutex_init(mesh->runtime.eval_mutex);
|
BLI_mutex_init(mesh->runtime.eval_mutex);
|
||||||
mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
|
mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
|
||||||
BLI_mutex_init(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.
|
/* 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
|
* 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.) */
|
* 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->bvh_cache = NULL;
|
||||||
runtime->shrinkwrap_data = NULL;
|
runtime->shrinkwrap_data = NULL;
|
||||||
|
|
||||||
mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
|
mesh_runtime_init_mutexes(mesh);
|
||||||
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 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)
|
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) {
|
if (mesh->runtime.mesh_eval != NULL) {
|
||||||
mesh->runtime.mesh_eval->edit_mesh = NULL;
|
mesh->runtime.mesh_eval->edit_mesh = NULL;
|
||||||
BKE_id_free(NULL, mesh->runtime.mesh_eval);
|
BKE_id_free(NULL, mesh->runtime.mesh_eval);
|
||||||
|
|
Loading…
Reference in New Issue