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 | |
parent | 060fdb49d64857ff1cbf9937420ed70b10b17086 (diff) | |
parent | cbc7aa80d49e3b36c9ecc0e27ec528b34c491fc1 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
10 files changed, 92 insertions, 51 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; } diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index eb7f186702b..afa20e3d766 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -1101,7 +1101,7 @@ static void task_parallel_range_ex( } task_scheduler = BLI_task_scheduler_get(); - task_pool = BLI_task_pool_create(task_scheduler, &state); + task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); num_threads = BLI_task_scheduler_num_threads(task_scheduler); /* The idea here is to prevent creating task for each of the loop iterations @@ -1124,6 +1124,9 @@ static void task_parallel_range_ex( } num_tasks = min_ii(num_tasks, (stop - start) / state.chunk_size); + + /* NOTE: This way we are adding a memory barrier and ensure all worker + * threads can read and modify the value, without any locks. */ atomic_fetch_and_add_int32(&state.iter, 0); if (use_userdata_chunk) { @@ -1325,7 +1328,7 @@ void BLI_task_parallel_listbase( } task_scheduler = BLI_task_scheduler_get(); - task_pool = BLI_task_pool_create(task_scheduler, &state); + task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); num_threads = BLI_task_scheduler_num_threads(task_scheduler); /* The idea here is to prevent creating task for each of the loop iterations @@ -1413,7 +1416,7 @@ void BLI_task_parallel_mempool( } task_scheduler = BLI_task_scheduler_get(); - task_pool = BLI_task_pool_create(task_scheduler, &state); + task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); num_threads = BLI_task_scheduler_num_threads(task_scheduler); /* The idea here is to prevent creating task for each of the loop iterations diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 60562641c93..3502ca69414 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -985,7 +985,7 @@ void DepsgraphNodeBuilder::build_obdata_geom(Object *object) // TODO: "Done" operation - /* Cloyth modifier. */ + /* Cloth modifier. */ LINKLIST_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Cloth) { build_cloth(object); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 3fb19adbb5c..10cf6f906de 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -923,7 +923,7 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) /* Animation curves and NLA. */ build_animdata_curves(id); /* Drivers. */ - build_animdata_drievrs(id); + build_animdata_drivers(id); } void DepsgraphRelationBuilder::build_animdata_curves(ID *id) @@ -992,7 +992,7 @@ void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id) } } -void DepsgraphRelationBuilder::build_animdata_drievrs(ID *id) +void DepsgraphRelationBuilder::build_animdata_drivers(ID *id) { AnimData *adt = BKE_animdata_from_id(id); if (adt == NULL) { @@ -1922,7 +1922,8 @@ void DepsgraphRelationBuilder::build_gpencil(bGPdata *gpd) // TODO: parent object (when that feature is implemented) } -void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file) { +void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file) +{ /* Animation. */ build_animdata(&cache_file->id); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 9f661b8e825..9227957adb4 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -206,7 +206,7 @@ struct DepsgraphRelationBuilder void build_animdata(ID *id); void build_animdata_curves(ID *id); void build_animdata_curves_targets(ID *id); - void build_animdata_drievrs(ID *id); + void build_animdata_drivers(ID *id); void build_driver(ID *id, FCurve *fcurve); void build_driver_data(ID *id, FCurve *fcurve); void build_driver_variables(ID *id, FCurve *fcurve); diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index 1d63b3aee43..ccaa9ecb8de 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -126,7 +126,7 @@ typedef struct tJoinArmature_AdtFixData { GHash *names_map; } tJoinArmature_AdtFixData; -/* Callback to pass to void BKE_animdata_main_cb() for fixing driver ID's to point to the new ID */ +/* Callback to pass to BKE_animdata_main_cb() for fixing driver ID's to point to the new ID */ /* FIXME: For now, we only care about drivers here. When editing rigs, it's very rare to have animation * on the rigs being edited already, so it should be safe to skip these. */ diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index d43b7511977..30a18ddc8bc 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1711,7 +1711,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN } else if (but->type == UI_BTYPE_SEARCH_MENU) { /* In case we fail to find proper searchprop, so other code might have already set but->type to search menu... */ - but->type = UI_BTYPE_LABEL; + but->flag |= UI_BUT_DISABLED; } } |