diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-01-03 15:44:47 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-01-03 15:44:47 +0300 |
commit | be403891652a375e5a0ac61b493342ca6d39afb7 (patch) | |
tree | ef9637103db6d66c4b311cba5b705d575562a1f8 /source/blender/blenkernel | |
parent | 060fdb49d64857ff1cbf9937420ed70b10b17086 (diff) | |
parent | cbc7aa80d49e3b36c9ecc0e27ec528b34c491fc1 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_subsurf.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 74 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequencer.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 33 |
4 files changed, 78 insertions, 41 deletions
diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 92170325113..d7b9d20d7b0 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -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 diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index c21c16adc85..68283b4a3aa 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -173,10 +173,11 @@ typedef struct MeshCalcNormalsData { const MLoop *mloop; MVert *mverts; float (*pnors)[3]; + float (*lnors_weighted)[3]; float (*vnors)[3]; } MeshCalcNormalsData; -static void mesh_calc_normals_poly_task_cb(void *userdata, const int pidx) +static void mesh_calc_normals_poly_cb(void *userdata, const int pidx) { MeshCalcNormalsData *data = userdata; const MPoly *mp = &data->mpolys[pidx]; @@ -184,7 +185,7 @@ static void mesh_calc_normals_poly_task_cb(void *userdata, const int pidx) BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]); } -static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) +static void mesh_calc_normals_poly_prepare_cb(void *userdata, const int pidx) { MeshCalcNormalsData *data = userdata; const MPoly *mp = &data->mpolys[pidx]; @@ -193,7 +194,7 @@ static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) float pnor_temp[3]; float *pnor = data->pnors ? data->pnors[pidx] : pnor_temp; - float (*vnors)[3] = data->vnors; + float (*lnors_weighted)[3] = data->lnors_weighted; const int nverts = mp->totloop; float (*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts); @@ -220,42 +221,62 @@ static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) v_prev = v_curr; } if (UNLIKELY(normalize_v3(pnor) == 0.0f)) { - pnor[2] = 1.0f; /* other axis set to 0.0 */ + pnor[2] = 1.0f; /* other axes set to 0.0 */ } } /* accumulate angle weighted face normal */ - /* inline version of #accumulate_vertex_normals_poly_v3 */ + /* inline version of #accumulate_vertex_normals_poly_v3, + * split between this threaded callback and #mesh_calc_normals_poly_accum_cb. */ { const float *prev_edge = edgevecbuf[nverts - 1]; for (i = 0; i < nverts; i++) { + const int lidx = mp->loopstart + i; const float *cur_edge = edgevecbuf[i]; /* calculate angle between the two poly edges incident on * this vertex */ const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); - /* accumulate */ - for (int k = 3; k--; ) { - atomic_add_and_fetch_fl(&vnors[ml[i].v][k], pnor[k] * fac); - } + /* Store for later accumulation */ + mul_v3_v3fl(lnors_weighted[lidx], pnor, fac); + prev_edge = cur_edge; } } +} + +static void mesh_calc_normals_poly_accum_cb(void *userdata, const int lidx) +{ + MeshCalcNormalsData *data = userdata; + + add_v3_v3(data->vnors[data->mloop[lidx].v], data->lnors_weighted[lidx]); +} + +static void mesh_calc_normals_poly_finalize_cb(void *userdata, const int vidx) +{ + MeshCalcNormalsData *data = userdata; + + MVert *mv = &data->mverts[vidx]; + float *no = data->vnors[vidx]; + + if (UNLIKELY(normalize_v3(no) == 0.0f)) { + /* following Mesh convention; we use vertex coordinate itself for normal in this case */ + normalize_v3_v3(no, mv->co); + } + normal_float_to_short_v3(mv->no, no); } void BKE_mesh_calc_normals_poly( MVert *mverts, float (*r_vertnors)[3], int numVerts, const MLoop *mloop, const MPoly *mpolys, - int UNUSED(numLoops), int numPolys, float (*r_polynors)[3], + int numLoops, int numPolys, float (*r_polynors)[3], const bool only_face_normals) { + const bool do_threaded = (numPolys > BKE_MESH_OMP_LIMIT); float (*pnors)[3] = r_polynors; - float (*vnors)[3] = r_vertnors; - bool free_vnors = false; - int i; if (only_face_normals) { BLI_assert((pnors != NULL) || (numPolys == 0)); @@ -265,10 +286,14 @@ void BKE_mesh_calc_normals_poly( .mpolys = mpolys, .mloop = mloop, .mverts = mverts, .pnors = pnors, }; - BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_task_cb, (numPolys > BKE_MESH_OMP_LIMIT)); + BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_cb, do_threaded); return; } + float (*vnors)[3] = r_vertnors; + float (*lnors_weighted)[3] = MEM_mallocN(sizeof(*lnors_weighted) * (size_t)numLoops, __func__); + bool free_vnors = false; + /* first go through and calculate normals for all the polys */ if (vnors == NULL) { vnors = MEM_callocN(sizeof(*vnors) * (size_t)numVerts, __func__); @@ -279,26 +304,23 @@ void BKE_mesh_calc_normals_poly( } MeshCalcNormalsData data = { - .mpolys = mpolys, .mloop = mloop, .mverts = mverts, .pnors = pnors, .vnors = vnors, + .mpolys = mpolys, .mloop = mloop, .mverts = mverts, + .pnors = pnors, .lnors_weighted = lnors_weighted, .vnors = vnors }; - BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_accum_task_cb, (numPolys > BKE_MESH_OMP_LIMIT)); - - for (i = 0; i < numVerts; i++) { - MVert *mv = &mverts[i]; - float *no = vnors[i]; + /* Compute poly normals, and prepare weighted loop normals. */ + BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, do_threaded); - if (UNLIKELY(normalize_v3(no) == 0.0f)) { - /* following Mesh convention; we use vertex coordinate itself for normal in this case */ - normalize_v3_v3(no, mv->co); - } + /* Actually accumulate weighted loop normals into vertex ones. */ + BLI_task_parallel_range(0, numLoops, &data, mesh_calc_normals_poly_accum_cb, do_threaded); - normal_float_to_short_v3(mv->no, no); - } + /* Normalize and validate computed vertex normals. */ + BLI_task_parallel_range(0, numVerts, &data, mesh_calc_normals_poly_finalize_cb, do_threaded); if (free_vnors) { MEM_freeN(vnors); } + MEM_freeN(lnors_weighted); } void BKE_mesh_calc_normals(Mesh *mesh) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 2319d36ab16..ee11a9806f3 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -4501,8 +4501,10 @@ Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame) for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame) continue; - /* only use elements you can see - not */ - if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIE, SEQ_TYPE_COLOR)) { + /* Only use strips that generate an image, not ones that combine + * other strips or apply some effect. */ + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, + SEQ_TYPE_MOVIE, SEQ_TYPE_COLOR, SEQ_TYPE_TEXT)) { if (seq->machine > best_machine) { best_seq = seq; best_machine = seq->machine; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 2f9a7090caf..b2f859ad1f5 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -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,21 +1489,24 @@ 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; + EdgeHash *ehash; - ccgdm->ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData); + ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData); medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm); for (i = 0; i < ccgdm->dm.numEdgeData; i++) { - BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i)); + BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i)); } + + atomic_cas_ptr((void**)&ccgdm->ehash, ccgdm->ehash, ehash); } - 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 +1549,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) @@ -3796,6 +3796,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); } } @@ -3810,14 +3814,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); @@ -3832,7 +3836,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; } @@ -4784,6 +4788,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; } |