Subsurf: Avoid global lock for loops and orig index layers

This is a bit annoying to have per-DM locking, but it's way better (as in, up to
4 times better) for playback speed when having lots of subsurf objects,
This commit is contained in:
Sergey Sharybin 2017-12-22 12:45:06 +01:00
parent 50f1c9a8af
commit df0ecd73af
Notes: blender-bot 2023-02-14 06:17:19 +01:00
Referenced by issue #53683, 2.79a release
2 changed files with 21 additions and 11 deletions

View File

@ -34,6 +34,9 @@
/* struct DerivedMesh is used directly */
#include "BKE_DerivedMesh.h"
/* Thread sync primitives used directly. */
#include "BLI_threads.h"
struct CCGElem;
struct DMFlagMat;
struct DMGridAdjacency;
@ -140,6 +143,9 @@ typedef struct CCGDerivedMesh {
} multires;
struct EdgeHash *ehash;
ThreadRWMutex loops_cache_rwlock;
ThreadRWMutex origindex_cache_rwlock;
} CCGDerivedMesh;
#ifdef WITH_OPENSUBDIV

View File

@ -90,9 +90,6 @@
/* assumes MLoop's are layed out 4 for each poly, in order */
#define USE_LOOP_LAYOUT_FAST
static ThreadRWMutex loops_cache_rwlock = BLI_RWLOCK_INITIALIZER;
static ThreadRWMutex origindex_cache_rwlock = BLI_RWLOCK_INITIALIZER;
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int drawInteriorEdges,
int useSubsurfUv,
@ -1492,7 +1489,7 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
/* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
if (!ccgdm->ehash) {
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
BLI_rw_mutex_lock(&ccgdm->loops_cache_rwlock, THREAD_LOCK_WRITE);
if (!ccgdm->ehash) {
MEdge *medge;
@ -1503,10 +1500,10 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
}
}
BLI_rw_mutex_unlock(&loops_cache_rwlock);
BLI_rw_mutex_unlock(&ccgdm->loops_cache_rwlock);
}
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_READ);
BLI_rw_mutex_lock(&ccgdm->loops_cache_rwlock, THREAD_LOCK_READ);
totface = ccgSubSurf_getNumFaces(ss);
mv = mloop;
for (index = 0; index < totface; index++) {
@ -1549,7 +1546,7 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
}
}
}
BLI_rw_mutex_unlock(&loops_cache_rwlock);
BLI_rw_mutex_unlock(&ccgdm->loops_cache_rwlock);
}
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
@ -4050,6 +4047,10 @@ static void ccgDM_release(DerivedMesh *dm)
MEM_freeN(ccgdm->edgeMap);
MEM_freeN(ccgdm->faceMap);
}
BLI_rw_mutex_end(&ccgdm->loops_cache_rwlock);
BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
MEM_freeN(ccgdm);
}
}
@ -4064,14 +4065,14 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
int a, index, totnone, totorig;
/* Avoid re-creation if the layer exists already */
BLI_rw_mutex_lock(&origindex_cache_rwlock, THREAD_LOCK_READ);
BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ);
origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
BLI_rw_mutex_unlock(&origindex_cache_rwlock);
BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
if (origindex) {
return origindex;
}
BLI_rw_mutex_lock(&origindex_cache_rwlock, THREAD_LOCK_WRITE);
BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE);
DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
@ -4086,7 +4087,7 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
CCGVert *v = ccgdm->vertMap[index].vert;
origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
}
BLI_rw_mutex_unlock(&origindex_cache_rwlock);
BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
return origindex;
}
@ -5041,6 +5042,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
ccgdm->dm.numTessFaceData = 0;
BLI_rw_mutex_init(&ccgdm->loops_cache_rwlock);
BLI_rw_mutex_init(&ccgdm->origindex_cache_rwlock);
return ccgdm;
}