Fix T52149: LoopTriArray computation was not correctly protected against concurrency.
Note: this commit seems to work as expected (also with transform snapping etc.). However, it is rather unsafe - not enough for 2.79 at least, unless we get much more testing on it. It also depends on three previous ones. Note that using a global lock here is far from ideal, we should rather have a lock per DM, but that will do for now, whole DM thing is doomed to oblivion anyway in 2.8. Also, we may need a `DM_DIRTY_LOOPTRIS` dirty flag at some point. Looks like we can survive without it for now though... Probably because cached looptris are never copied accross DM's?
This commit is contained in:
parent
c034193821
commit
00cb352790
Notes:
blender-bot
2023-02-14 06:46:23 +01:00
Referenced by issue #52149, Crash on entering Edit Mode of high poly mesh used by Shrink Wrap
|
@ -220,7 +220,7 @@ struct DerivedMesh {
|
|||
/** Recalculates mesh tessellation */
|
||||
void (*recalcTessellation)(DerivedMesh *dm);
|
||||
|
||||
/** Loop tessellation cache */
|
||||
/** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
|
||||
void (*recalcLoopTri)(DerivedMesh *dm);
|
||||
/** accessor functions */
|
||||
const struct MLoopTri *(*getLoopTriArray)(DerivedMesh * dm);
|
||||
|
|
|
@ -93,6 +93,10 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
|
|||
# define ASSERT_IS_VALID_DM(dm)
|
||||
#endif
|
||||
|
||||
|
||||
static ThreadMutex loops_cache_lock = BLI_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
|
||||
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
|
||||
|
||||
|
@ -241,7 +245,13 @@ static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm)
|
|||
BLI_assert(dm->getNumLoopTri(dm) == dm->looptris.num);
|
||||
}
|
||||
else {
|
||||
dm->recalcLoopTri(dm);
|
||||
BLI_mutex_lock(&loops_cache_lock);
|
||||
/* We need to ensure array is still NULL inside mutex-protected code, some other thread might have already
|
||||
* recomputed those looptris. */
|
||||
if (dm->looptris.array == NULL) {
|
||||
dm->recalcLoopTri(dm);
|
||||
}
|
||||
BLI_mutex_unlock(&loops_cache_lock);
|
||||
}
|
||||
return dm->looptris.array;
|
||||
}
|
||||
|
|
|
@ -4474,10 +4474,10 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
|
|||
/* Nothing to do: CCG handles creating its own tessfaces */
|
||||
}
|
||||
|
||||
/* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
|
||||
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
|
||||
{
|
||||
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
|
||||
MLoopTri *mlooptri;
|
||||
MLoopTri *mlooptri = dm->looptris.array;
|
||||
const int tottri = dm->numPolyData * 2;
|
||||
int i, poly_index;
|
||||
|
||||
|
@ -4502,7 +4502,6 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm)
|
|||
lt->tri[2] = (poly_index * 4) + 2;
|
||||
lt->poly = poly_index;
|
||||
}
|
||||
BLI_rw_mutex_unlock(&loops_cache_rwlock);
|
||||
}
|
||||
|
||||
static void ccgDM_calcNormals(DerivedMesh *dm)
|
||||
|
|
Loading…
Reference in New Issue