diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-09 17:13:26 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-13 13:57:51 +0400 |
commit | e618d8238e0e065bdfd2d9332ba7231e870a7e7d (patch) | |
tree | 4e17fe3e2aa16ba0bdd92c98ec5f206efac358f1 /source/blender/editors | |
parent | ac077f016d3667a3b15853ac79b272cb0b6fd661 (diff) |
Fix T38054: High CPU usage with many objects
This is a regression since threaded dependency graph landed to master.
Root of the issue goes to the loads of graph preparation being done
even if there's nothing to be updated.
The idea of this change is to use ID type recalc bits to determine
whether there're objects to be updated. Generally speaking, we now
check object and object data datablocks with DAG_id_type_tagged()
and if there's no such IDs tagged we skip the whole task pool creation
and so,
The only difficult aspect was that in some circumstances it was possible
that there are tagged objects but nothing in ID recalc bit fields.
There were several different circumstances when it was possible:
* When one assigns object->recalc flag directly DAG flush didn't
set corresponding bits to ID recalc bits. Partially it is fixed
by making it so flush will set bitfield, but also for object
types there's no reason to assign recalc flag directly. Using
generic DAG_id_type_tag works almost the same fast as direct
assignment, ensures all the bitflags are set properly and for the
long run it seems it's what we would actually want to.
* DAG_on_visible_update() didn't set recalc bits at all.
* Some areas were checking for object->recalc != 0, however it is was
possible that object recalc flag contains PSYS_RECALC_CHILD which
was never cleaned from there.
No idea why would we need to assign such a flag when enabling
scene simplification, this is to be investigated separately.
* 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.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 5 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 8 |
2 files changed, 7 insertions, 6 deletions
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 */ |