Subsurf: Avoid global lock for loops and orig index layers
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 22 Dec 2017 11:45:06 +0000 (12:45 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 22 Dec 2017 11:50:57 +0000 (12:50 +0100)
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,

source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/subsurf_ccg.c

index 92170325113df91bf8a53d27af62dc37f20fbf29..d7b9d20d7b0994cc93fbaa841a86e3e581f1f5de 100644 (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
index f8025f8df84a2269e07b3e713563d29c4e598ed8..1386c23e234881a6e04174fc65f6709e69cad0de 100644 (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;
 }