diff options
8 files changed, 140 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 13f0c2977c2..01327452831 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2031,7 +2031,7 @@ void DAG_scene_update_flags(Main *bmain, Scene *scene, unsigned int lay, const s /* test: set time flag, to disable baked systems to update */ for (SETLOOPER(scene, sce_iter, base)) { ob = base->object; - if (ob->recalc) + if (ob->recalc & OB_RECALC_ALL) ob->recalc |= OB_RECALC_TIME; } @@ -2115,10 +2115,14 @@ static void dag_group_on_visible_update(Group *group) group->id.flag |= LIB_DOIT; for (go = group->gobject.first; go; go = go->next) { - if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) + if (ELEM6(go->ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { go->ob->recalc |= OB_RECALC_DATA; - if (go->ob->proxy_from) + lib_id_recalc_tag(G.main, &go->ob->id); + } + if (go->ob->proxy_from) { go->ob->recalc |= OB_RECALC_OB; + lib_id_recalc_tag(G.main, &go->ob->id); + } if (go->ob->dup_group) dag_group_on_visible_update(go->ob->dup_group); @@ -2156,10 +2160,14 @@ void DAG_on_visible_update(Main *bmain, const short do_time) oblay = (node) ? node->lay : ob->lay; if ((oblay & lay) & ~scene->lay_updated) { - if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) + if (ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) { ob->recalc |= OB_RECALC_DATA; - if (ob->proxy && (ob->proxy_group == NULL)) + lib_id_recalc_tag(bmain, &ob->id); + } + if (ob->proxy && (ob->proxy_group == NULL)) { ob->proxy->recalc |= OB_RECALC_DATA; + lib_id_recalc_tag(bmain, &ob->id); + } if (ob->dup_group) dag_group_on_visible_update(ob->dup_group); } @@ -2210,6 +2218,13 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) ob = (Object *)id; BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH); + /* So if someone tagged object recalc directly, + * id_tag_update biffield stays relevant + */ + if (ob->recalc & OB_RECALC_ALL) { + DAG_id_type_tag(bmain, GS(id->name)); + } + if (ob->recalc & OB_RECALC_DATA) { /* all users of this ob->data should be checked */ id = ob->data; @@ -2311,6 +2326,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id) CONSTRAINT_TYPE_OBJECTSOLVER)) { obt->recalc |= OB_RECALC_OB; + lib_id_recalc_tag(bmain, &obt->id); break; } } @@ -2427,12 +2443,34 @@ void DAG_ids_check_recalc(Main *bmain, Scene *scene, int time) dag_editors_scene_update(bmain, scene, (updated || time)); } +/* It is possible that scene_update_post and frame_update_post handlers + * will modify objects. The issue is that DAG_ids_clear_recalc is called + * just after callbacks, which leaves objects with recalc flags but no + * corresponding bit in ID recalc bitfield. This leads to some kind of + * regression when using ID type tag fields to check whether there objects + * to be updated internally comparing threaded DAG with legacy one. + * + * For now let's have a workaround which will preserve tag for ID_OB + * if there're objects with OB_RECALC_ALL bits. This keeps behavior + * unchanged comparing with 2.69 release. + * + * TODO(sergey): Need to get rid of such a workaround. + * + * - sergey - + */ + +#define POST_UPDATE_HANDLER_WORKAROUND + void DAG_ids_clear_recalc(Main *bmain) { ListBase *lbarray[MAX_LIBARRAY]; bNodeTree *ntree; int a; +#ifdef POST_UPDATE_HANDLER_WORKAROUND + bool have_updated_objects = false; +#endif + /* loop over all ID types */ a = set_listbasepointers(bmain, lbarray); @@ -2447,6 +2485,15 @@ void DAG_ids_clear_recalc(Main *bmain) if (id->flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA)) id->flag &= ~(LIB_ID_RECALC | LIB_ID_RECALC_DATA); +#ifdef POST_UPDATE_HANDLER_WORKAROUND + if (GS(id->name) == ID_OB) { + Object *object = (Object *) id; + if (object->recalc & OB_RECALC_ALL) { + have_updated_objects = true; + } + } +#endif + /* some ID's contain semi-datablock nodetree */ ntree = ntreeFromID(id); if (ntree && (ntree->id.flag & (LIB_ID_RECALC | LIB_ID_RECALC_DATA))) @@ -2456,6 +2503,12 @@ void DAG_ids_clear_recalc(Main *bmain) } memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update)); + +#ifdef POST_UPDATE_HANDLER_WORKAROUND + if (have_updated_objects) { + DAG_id_type_tag(bmain, ID_OB); + } +#endif } void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag) diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 821df59c67d..f2264190a5c 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -553,6 +553,8 @@ void BKE_main_lib_objects_recalc_all(Main *bmain) for (ob = bmain->object.first; ob; ob = ob->id.next) if (ob->id.lib) ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; + + DAG_id_type_tag(bmain, ID_OB); } /** diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index e489759e312..4d8075e9cba 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1365,18 +1365,80 @@ static void print_threads_statistics(ThreadedObjectUpdateState *state) #endif } -static void scene_update_objects(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent) +static bool scene_need_update_objects(Main *bmain) +{ + return + /* Object datablocks themselves (for OB_RECALC_OB) */ + DAG_id_type_tagged(bmain, ID_OB) || + + /* Objects data datablocks (for OB_RECALC_DATA) */ + DAG_id_type_tagged(bmain, ID_ME) || /* Mesh */ + DAG_id_type_tagged(bmain, ID_CU) || /* Curve */ + DAG_id_type_tagged(bmain, ID_MB) || /* MetaBall */ + DAG_id_type_tagged(bmain, ID_LA) || /* Lamp */ + DAG_id_type_tagged(bmain, ID_LT) || /* Lattice */ + DAG_id_type_tagged(bmain, ID_CA) || /* Camera */ + DAG_id_type_tagged(bmain, ID_KE) || /* KE */ + DAG_id_type_tagged(bmain, ID_SPK) || /* Speaker */ + DAG_id_type_tagged(bmain, ID_AR); /* Armature */ +} + +static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent) { TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; ThreadedObjectUpdateState state; + /* Early check for whether we need to invoke all the task-based + * tihngs (spawn new ppol, traverse dependency graph and so on). + * + * Basically if there's no ID datablocks tagged for update which + * corresponds to object->recalc flags (which are checked in + * BKE_object_handle_update() then we do nothing here. + */ + if (!scene_need_update_objects(bmain)) { + /* For debug builds we check whether early return didn't give + * us any regressions in terms of missing updates. + * + * TODO(sergey): Remove once we're sure the check above is correct. + */ +#ifndef NDEBUG + Base *base; + + for (base = scene->base.first; base; base = base->next) { + Object *object = base->object; + + BLI_assert((object->recalc & OB_RECALC_ALL) == 0); + + if (object->proxy) { + BLI_assert((object->proxy->recalc & OB_RECALC_ALL) == 0); + } + + if (object->dup_group && (object->transflag & OB_DUPLIGROUP)) { + GroupObject *go; + for (go = object->dup_group->gobject.first; go; go = go->next) { + if (go->ob) { + BLI_assert((go->ob->recalc & OB_RECALC_ALL) == 0); + } + } + } + } +#endif + + return; + } + state.eval_ctx = eval_ctx; state.scene = scene; state.scene_parent = scene_parent; - memset(state.statistics, 0, sizeof(state.statistics)); - state.has_updated_objects = false; - state.base_time = PIL_check_seconds_timer(); + + /* Those are only needed when blender is run with --debug argument. */ + if (G.debug & G_DEBUG) { + memset(state.statistics, 0, sizeof(state.statistics)); + state.has_updated_objects = false; + state.base_time = PIL_check_seconds_timer(); + } + #ifdef MBALL_SINGLETHREAD_HACK state.has_mballs = false; #endif @@ -1408,7 +1470,7 @@ static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bma scene_update_tagged_recursive(eval_ctx, bmain, scene->set, scene_parent); /* scene objects */ - scene_update_objects(eval_ctx, scene, scene_parent); + scene_update_objects(eval_ctx, bmain, scene, scene_parent); /* scene drivers... */ scene_update_drivers(bmain, scene); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 8475512cdaa..9f70135b787 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -113,7 +113,10 @@ void EDBM_mesh_ensure_valid_dm_hack(Scene *scene, BMEditMesh *em) if ((((ID *)em->ob->data)->flag & LIB_ID_RECALC) || (em->ob->recalc & OB_RECALC_DATA)) { - em->ob->recalc |= OB_RECALC_DATA; /* since we may not have done selection flushing */ + /* since we may not have done selection flushing */ + if ((em->ob->recalc & OB_RECALC_DATA) == 0) { + DAG_id_tag_update(&em->ob->id, OB_RECALC_DATA); + } BKE_object_handle_update(G.main->eval_ctx, scene, em->ob); } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 2c001ca6527..55b114b60ef 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4943,8 +4943,7 @@ static void set_trans_object_base_flags(TransInfo *t) base->flag |= BA_WAS_SEL; } } - /* used for flush, depgraph will change recalcs if needed :) */ - ob->recalc |= OB_RECALC_OB; + DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } @@ -5018,8 +5017,7 @@ static int count_proportional_objects(TransInfo *t) (BASE_EDITABLE_BGMODE(v3d, scene, base))) { - /* used for flush, depgraph will change recalcs if needed :) */ - ob->recalc |= OB_RECALC_OB; + DAG_id_tag_update(&ob->id, OB_RECALC_OB); total += 1; } @@ -5833,7 +5831,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* pointcache refresh */ if (BKE_ptcache_object_reset(t->scene, ob, PTCACHE_RESET_OUTDATED)) - ob->recalc |= OB_RECALC_DATA; + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* Needed for proper updating of "quick cached" dynamics. */ /* Creates troubles for moving animated objects without */ diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index d665a0630ac..8d8b39a6358 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -42,6 +42,7 @@ extern "C" { #include "DNA_screen_types.h" #include "BKE_customdata.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" /* free_libblock */ #include "BKE_main.h" /* struct Main */ @@ -471,7 +472,7 @@ Object *BlenderStrokeRenderer::NewMesh() const #else (void)base; #endif - ob->recalc = OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; + DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); return ob; } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 46edb48fde1..e7edf413f3a 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1270,6 +1270,7 @@ static void object_simplify_update(Object *ob) for (md = ob->modifiers.first; md; md = md->next) { if (ELEM3(md->type, eModifierType_Subsurf, eModifierType_Multires, eModifierType_ParticleSystem)) { + /* TODO(sergey): Figure out what da heck we're using PSYS flag on object. */ ob->recalc |= PSYS_RECALC_CHILD; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 382229cca88..57d7a87199c 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5146,7 +5146,9 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l normalize_m4_m4(mat, camera->obmat); invert_m4(mat); RE_SetView(re, mat); - camera->recalc= OB_RECALC_OB; /* force correct matrix for scaled cameras */ + + /* force correct matrix for scaled cameras */ + DAG_id_tag_update(&camera->id, OB_RECALC_OB); } /* store for incremental render, viewmat rotates dbase */ |