diff options
Diffstat (limited to 'source/blender/depsgraph/intern')
27 files changed, 574 insertions, 391 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 086fd0c1144..e7f54f9b0cb 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -36,135 +36,28 @@ #include "BLI_utildefines.h" #include "BLI_ghash.h" -#include "BLI_stack.h" #include "intern/depsgraph.h" #include "intern/depsgraph_types.h" #include "intern/nodes/deg_node.h" -#include "intern/nodes/deg_node_component.h" -#include "intern/nodes/deg_node_operation.h" - -#include "util/deg_util_foreach.h" - -#include <cstdio> namespace DEG { -static bool check_object_needs_evaluation(Object *object) -{ - if (object->recalc & OB_RECALC_ALL) { - /* Object is tagged for update anyway, no need to re-tag it. */ - return false; - } - if (object->type == OB_MESH) { - return object->derivedFinal == NULL; - } - else if (ELEM(object->type, - OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_LATTICE)) - { - return object->curve_cache == NULL; - } - return false; -} - -void deg_graph_build_flush_layers(Depsgraph *graph) -{ - BLI_Stack *stack = BLI_stack_new(sizeof(OperationDepsNode*), - "DEG flush layers stack"); - foreach (OperationDepsNode *node, graph->operations) { - IDDepsNode *id_node = node->owner->owner; - node->done = 0; - node->num_links_pending = 0; - foreach (DepsRelation *rel, node->outlinks) { - if ((rel->from->type == DEG_NODE_TYPE_OPERATION) && - (rel->flag & DEPSREL_FLAG_CYCLIC) == 0) - { - ++node->num_links_pending; - } - } - if (node->num_links_pending == 0) { - BLI_stack_push(stack, &node); - node->done = 1; - } - node->owner->layers = id_node->layers; - id_node->id->tag |= LIB_TAG_DOIT; - } - while (!BLI_stack_is_empty(stack)) { - OperationDepsNode *node; - BLI_stack_pop(stack, &node); - /* Flush layers to parents. */ - foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEG_NODE_TYPE_OPERATION) { - OperationDepsNode *from = (OperationDepsNode *)rel->from; - from->owner->layers |= node->owner->layers; - } - } - /* Schedule parent nodes. */ - foreach (DepsRelation *rel, node->inlinks) { - if (rel->from->type == DEG_NODE_TYPE_OPERATION) { - OperationDepsNode *from = (OperationDepsNode *)rel->from; - if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { - BLI_assert(from->num_links_pending > 0); - --from->num_links_pending; - } - if (from->num_links_pending == 0 && from->done == 0) { - BLI_stack_push(stack, &from); - from->done = 1; - } - } - } - } - BLI_stack_free(stack); -} - void deg_graph_build_finalize(Depsgraph *graph) { - /* STEP 1: Make sure new invisible dependencies are ready for use. - * - * TODO(sergey): This might do a bit of extra tagging, but it's kinda nice - * to do it ahead of a time and don't spend time on flushing updates on - * every frame change. - */ - GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash) - { - if (id_node->layers == 0) { - ID *id = id_node->id; - if (GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if (check_object_needs_evaluation(object)) { - id_node->tag_update(graph); - } - } - } - } - GHASH_FOREACH_END(); - /* STEP 2: Flush visibility layers from children to parent. */ - deg_graph_build_flush_layers(graph); - /* STEP 3: Re-tag IDs for update if it was tagged before the relations + /* Re-tag IDs for update if it was tagged before the relations * update tag. */ GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash) { - GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp, id_node->components) - { - id_node->layers |= comp->layers; + ID *id = id_node->id; + if ((id->tag & LIB_TAG_ID_RECALC_ALL)) { + id_node->tag_update(graph); } - GHASH_FOREACH_END(); - - if ((id_node->layers & graph->layers) != 0 || graph->layers == 0) { - ID *id = id_node->id; - if ((id->tag & LIB_TAG_ID_RECALC_ALL) && - (id->tag & LIB_TAG_DOIT)) - { + else if (GS(id->name) == ID_OB) { + Object *object = (Object *)id; + if (object->recalc & OB_RECALC_ALL) { id_node->tag_update(graph); - id->tag &= ~LIB_TAG_DOIT; - } - else if (GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if (object->recalc & OB_RECALC_ALL) { - id_node->tag_update(graph); - id->tag &= ~LIB_TAG_DOIT; - } } } id_node->finalize_build(); diff --git a/source/blender/depsgraph/intern/builder/deg_builder.h b/source/blender/depsgraph/intern/builder/deg_builder.h index b8ea8c8e599..c0731eeac20 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.h +++ b/source/blender/depsgraph/intern/builder/deg_builder.h @@ -30,15 +30,10 @@ #pragma once -#include "intern/depsgraph_types.h" - -struct FCurve; - namespace DEG { struct Depsgraph; void deg_graph_build_finalize(struct Depsgraph *graph); -void deg_graph_build_flush_layers(struct Depsgraph *graph); } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 99d8834da1b..a95b498280a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -72,7 +72,6 @@ extern "C" { #include "BKE_animsys.h" #include "BKE_constraint.h" #include "BKE_curve.h" -#include "BKE_depsgraph.h" #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_idcode.h" @@ -125,7 +124,7 @@ static void modifier_walk(void *user_data, { BuilderWalkUserData *data = (BuilderWalkUserData *)user_data; if (*obpoin) { - data->builder->build_object(data->scene, NULL, *obpoin); + data->builder->build_object(data->scene, *obpoin); } } @@ -138,7 +137,7 @@ void constraint_walk(bConstraint * /*con*/, if (*idpoin) { ID *id = *idpoin; if (GS(id->name) == ID_OB) { - data->builder->build_object(data->scene, NULL, (Object *)id); + data->builder->build_object(data->scene, (Object *)id); } } } @@ -302,9 +301,7 @@ void DepsgraphNodeBuilder::begin_build(Main *bmain) { } FOREACH_NODETREE_END } -void DepsgraphNodeBuilder::build_group(Scene *scene, - Base *base, - Group *group) +void DepsgraphNodeBuilder::build_group(Scene *scene, Group *group) { ID *group_id = &group->id; if (group_id->tag & LIB_TAG_DOIT) { @@ -313,39 +310,27 @@ void DepsgraphNodeBuilder::build_group(Scene *scene, group_id->tag |= LIB_TAG_DOIT; LINKLIST_FOREACH (GroupObject *, go, &group->gobject) { - build_object(scene, base, go->ob); + build_object(scene, go->ob); } } -void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob) +void DepsgraphNodeBuilder::build_object(Scene *scene, Object *ob) { - const bool has_object = (ob->id.tag & LIB_TAG_DOIT); - IDDepsNode *id_node = (has_object) - ? m_graph->find_id_node(&ob->id) - : add_id_node(&ob->id); - /* Update node layers. - * Do it for both new and existing ID nodes. This is so because several - * bases might be sharing same object. - */ - if (base != NULL) { - id_node->layers |= base->lay; - } - if (ob == scene->camera) { - /* Camera should always be updated, it used directly by viewport. */ - id_node->layers |= (unsigned int)(-1); - } /* Skip rest of components if the ID node was already there. */ - if (has_object) { + if (ob->id.tag & LIB_TAG_DOIT) { return; } ob->id.tag |= LIB_TAG_DOIT; + + /* Create ID node for obejct and begin init. */ + IDDepsNode *id_node = add_id_node(&ob->id); ob->customdata_mask = 0; /* Standard components. */ build_object_transform(scene, ob); if (ob->parent != NULL) { - build_object(scene, NULL, ob->parent); + build_object(scene, ob->parent); } if (ob->modifiers.first != NULL) { BuilderWalkUserData data; @@ -431,12 +416,12 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob) /* Object that this is a proxy for. */ if (ob->proxy) { ob->proxy->proxy_from = ob; - build_object(scene, base, ob->proxy); + build_object(scene, ob->proxy); } /* Object dupligroup. */ if (ob->dup_group != NULL) { - build_group(scene, base, ob->dup_group); + build_group(scene, ob->dup_group); } } @@ -871,13 +856,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) */ Curve *cu = (Curve *)obdata; if (cu->bevobj != NULL) { - build_object(scene, NULL, cu->bevobj); + build_object(scene, cu->bevobj); } if (cu->taperobj != NULL) { - build_object(scene, NULL, cu->taperobj); + build_object(scene, cu->taperobj); } if (ob->type == OB_FONT && cu->textoncurve != NULL) { - build_object(scene, NULL, cu->textoncurve); + build_object(scene, cu->textoncurve); } break; } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index ba8a5d01cb0..83a4dfda8a5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -32,7 +32,6 @@ #include "intern/depsgraph_types.h" -struct Base; struct CacheFile; struct bGPdata; struct ListBase; @@ -42,6 +41,7 @@ struct Image; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Material; struct Mask; @@ -121,8 +121,8 @@ struct DepsgraphNodeBuilder { int name_tag = -1); void build_scene(Main *bmain, Scene *scene); - void build_group(Scene *scene, Base *base, Group *group); - void build_object(Scene *scene, Base *base, Object *ob); + void build_group(Scene *scene, Group *group); + void build_object(Scene *scene, Object *ob); void build_object_transform(Scene *scene, Object *ob); void build_object_constraints(Scene *scene, Object *ob); void build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan); @@ -157,6 +157,17 @@ struct DepsgraphNodeBuilder { void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); + struct LayerCollectionState { + int index; + LayerCollection *parent; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); protected: Main *m_bmain; Depsgraph *m_graph; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc new file mode 100644 index 00000000000..e419b72fee8 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer.cc @@ -0,0 +1,117 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph's nodes + */ + +#include "intern/builder/deg_builder_nodes.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_utildefines.h" + +#include "BKE_layer.h" + +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" +#include "intern/depsgraph_types.h" +#include "intern/depsgraph_intern.h" +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphNodeBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + /* TODO(sergey): This will attempt to create component for each collection. + * Harmless but could be optimized. + */ + ComponentDepsNode *comp = add_component_node(&scene->id, DEG_NODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + function_bind(BKE_layer_eval_layer_collection, + _1, + layer_collection, + state->parent), + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + ++state->index; + + /* Recurs into nested layer collections. */ + LayerCollection *parent = state->parent; + state->parent = layer_collection; + build_layer_collections(scene, &layer_collection->layer_collections, state); + state->parent = parent; +} + +void DepsgraphNodeBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphNodeBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + ComponentDepsNode *comp = add_component_node(&scene->id, DEG_NODE_TYPE_LAYER_COLLECTIONS); + + add_operation_node(comp, + function_bind(BKE_layer_eval_layer_collection_pre, _1, scene, scene_layer), + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + add_operation_node(comp, + function_bind(BKE_layer_eval_layer_collection_post, _1, scene_layer), + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.parent = NULL; + build_layer_collections(scene, &scene_layer->layer_collections, &state); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc index 2cf0f3a342f..8dd01fe9551 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc @@ -133,7 +133,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) /* Rebuild pose if not up to date. */ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild_ex(ob, arm, false); + BKE_pose_rebuild(ob, arm); /* XXX: Without this animation gets lost in certain circumstances * after loading file. Need to investigate further since it does * not happen with simple scenes.. diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc index 3249867e416..556db3bd651 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc @@ -43,9 +43,11 @@ extern "C" { #include "DNA_node_types.h" +#include "DNA_layer_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_node.h" } /* extern "C" */ @@ -79,9 +81,13 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) } /* scene objects */ - LINKLIST_FOREACH (Base *, base, &scene->base) { - Object *ob = base->object; - build_object(scene, base, ob); + int selection_color = 1; + for (SceneLayer *sl = (SceneLayer *)scene->render_layers.first; sl; sl = sl->next) { + for (Base *base = (Base *)sl->object_bases.first; base; base = base->next) { + /* object itself */ + build_object(scene, base->object); + base->selcol = selection_color++; + } } /* rigidbody */ @@ -126,6 +132,9 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene) LINKLIST_FOREACH (MovieClip *, clip, &bmain->movieclip) { build_movieclip(clip); } + + /* Collections. */ + build_scene_layer_collections(scene); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 72a7d04f627..69f04b20cd8 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -308,10 +308,10 @@ void DepsgraphRelationBuilder::add_operation_relation( } } -void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name) +void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name) { unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, eModifierType_Collision, dupli); + Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, eModifierType_Collision, dupli); for (unsigned int i = 0; i < numcollobj; i++) { @@ -363,7 +363,7 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, } if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) { - add_collision_relations(key, scene, ob, NULL, eff->ob->lay, true, "Force Absorption"); + add_collision_relations(key, scene, ob, NULL, true, "Force Absorption"); } } } @@ -1269,10 +1269,10 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) /* collisions */ if (part->type != PART_HAIR) { - add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision"); + add_collision_relations(psys_key, scene, ob, part->collision_group, true, "Particle Collision"); } else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) { - add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, ob->lay | scene->lay, true, "Hair Collision"); + add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, true, "Hair Collision"); } /* effectors */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 411f3be4036..edca1905873 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -45,7 +45,7 @@ #include "intern/nodes/deg_node.h" #include "intern/nodes/deg_node_operation.h" -struct Base; +struct BaseLegacy; struct bGPdata; struct CacheFile; struct ListBase; @@ -54,6 +54,7 @@ struct ID; struct FCurve; struct Group; struct Key; +struct LayerCollection; struct Main; struct Mask; struct Material; @@ -227,9 +228,23 @@ struct DepsgraphRelationBuilder void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); - void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name); + void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name); void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name); + struct LayerCollectionState { + int index; + OperationKey init_key; + OperationKey done_key; + OperationKey prev_key; + }; + void build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state); + void build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state); + void build_scene_layer_collections(Scene *scene); + template <typename KeyType> OperationDepsNode *find_operation_node(const KeyType &key); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc new file mode 100644 index 00000000000..a6c9fdfc6bc --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer.cc @@ -0,0 +1,127 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations_scene.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph + */ + +#include "intern/builder/deg_builder_relations.h" + +#include <stdio.h> +#include <stdlib.h> +#include <cstring> /* required for STREQ later on. */ + +#include "MEM_guardedalloc.h" + +extern "C" { +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_layer.h" +#include "BKE_main.h" +#include "BKE_node.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +} /* extern "C" */ + +#include "intern/builder/deg_builder.h" +#include "intern/builder/deg_builder_pchanmap.h" + +#include "intern/nodes/deg_node.h" +#include "intern/nodes/deg_node_component.h" +#include "intern/nodes/deg_node_operation.h" + +#include "intern/depsgraph_intern.h" +#include "intern/depsgraph_types.h" + +#include "util/deg_util_foreach.h" + +namespace DEG { + +void DepsgraphRelationBuilder::build_layer_collection(Scene *scene, + LayerCollection *layer_collection, + LayerCollectionState *state) +{ + OperationKey layer_key(&scene->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_EVAL, + layer_collection->scene_collection->name, + state->index); + add_relation(state->prev_key, layer_key, "Layer collection order"); + + ++state->index; + state->prev_key = layer_key; + + /* Recurs into nested layer collections. */ + build_layer_collections(scene, + &layer_collection->layer_collections, + state); +} + +void DepsgraphRelationBuilder::build_layer_collections(Scene *scene, + ListBase *layer_collections, + LayerCollectionState *state) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + /* Recurs into the layer. */ + build_layer_collection(scene, layer_collection, state); + } +} + +void DepsgraphRelationBuilder::build_scene_layer_collections(Scene *scene) +{ + LayerCollectionState state; + state.index = 0; + LINKLIST_FOREACH (SceneLayer *, scene_layer, &scene->render_layers) { + OperationKey init_key(&scene->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_INIT, + scene_layer->name); + OperationKey done_key(&scene->id, + DEG_NODE_TYPE_LAYER_COLLECTIONS, + DEG_OPCODE_SCENE_LAYER_DONE, + scene_layer->name); + + state.init_key = init_key; + state.done_key = done_key; + state.prev_key = init_key; + + build_layer_collections(scene, + &scene_layer->layer_collections, + &state); + + add_relation(state.prev_key, done_key, "Layer collection order"); + } +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc index 6a9568e7e8d..08a897df2aa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc @@ -46,6 +46,7 @@ extern "C" { #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_node.h" } /* extern "C" */ @@ -73,11 +74,15 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) build_scene(bmain, scene->set); } + /* XXX store scene to access from DAG_get_scene */ + m_graph->scene = scene; + /* scene objects */ - LINKLIST_FOREACH (Base *, base, &scene->base) { - Object *ob = base->object; + FOREACH_SCENE_OBJECT(scene, ob) + { build_object(bmain, scene, ob); } + FOREACH_SCENE_OBJECT_END /* rigidbody */ if (scene->rigidbody_world) { @@ -114,6 +119,9 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene) build_movieclip(clip); } + /* Collections. */ + build_scene_layer_collections(scene); + for (Depsgraph::OperationNodes::const_iterator it_op = m_graph->operations.begin(); it_op != m_graph->operations.end(); ++it_op) diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 07712e060ca..82b8ca65c7b 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -82,15 +82,16 @@ static const int deg_debug_node_type_color_map[][2] = { {DEG_NODE_TYPE_ID_REF, 2}, /* Outer Types */ - {DEG_NODE_TYPE_PARAMETERS, 3}, - {DEG_NODE_TYPE_PROXY, 4}, - {DEG_NODE_TYPE_ANIMATION, 5}, - {DEG_NODE_TYPE_TRANSFORM, 6}, - {DEG_NODE_TYPE_GEOMETRY, 7}, - {DEG_NODE_TYPE_SEQUENCER, 8}, - {DEG_NODE_TYPE_SHADING, 9}, - {DEG_NODE_TYPE_CACHE, 10}, - {-1, 0} + {DEG_NODE_TYPE_PARAMETERS, 3}, + {DEG_NODE_TYPE_PROXY, 4}, + {DEG_NODE_TYPE_ANIMATION, 5}, + {DEG_NODE_TYPE_TRANSFORM, 6}, + {DEG_NODE_TYPE_GEOMETRY, 7}, + {DEG_NODE_TYPE_SEQUENCER, 8}, + {DEG_NODE_TYPE_SHADING, 9}, + {DEG_NODE_TYPE_CACHE, 10}, + {DEG_NODE_TYPE_LAYER_COLLECTIONS, 11}, + {-1, 0} }; #endif @@ -178,7 +179,7 @@ static void deg_debug_graphviz_legend(const DebugContext &ctx) #ifdef COLOR_SCHEME_NODE_TYPE const int (*pair)[2]; for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; ++pair) { - DepsNodeFactory *nti = DEG_get_node_factory((eDepsNode_Type)(*pair)[0]); + DepsNodeFactory *nti = DEG_get_node_factory((eDEG_NODE_TYPE)(*pair)[0]); deg_debug_graphviz_legend_color(ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors]); @@ -285,12 +286,6 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx, const char *shape = "box"; string name = node->identifier(); float priority = -1.0f; - if (node->type == DEG_NODE_TYPE_ID_REF) { - IDDepsNode *id_node = (IDDepsNode *)node; - char buf[256]; - BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers); - name += buf; - } if (ctx.show_eval_priority && node->tclass == DEG_NODE_CLASS_OPERATION) { priority = ((OperationDepsNode *)node)->eval_priority; } @@ -321,12 +316,6 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const DepsNode *node) { string name = node->identifier(); - if (node->type == DEG_NODE_TYPE_ID_REF) { - IDDepsNode *id_node = (IDDepsNode *)node; - char buf[256]; - BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers); - name += buf; - } deg_debug_fprintf(ctx, "// %s\n", name.c_str()); deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node); // deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name); @@ -389,6 +378,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, case DEG_NODE_TYPE_BONE: case DEG_NODE_TYPE_SHADING: case DEG_NODE_TYPE_CACHE: + case DEG_NODE_TYPE_LAYER_COLLECTIONS: case DEG_NODE_TYPE_EVAL_PARTICLES: { ComponentDepsNode *comp_node = (ComponentDepsNode *)node; diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 330f8a0dcb6..8c9de1faeb2 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -46,8 +46,6 @@ extern "C" { #include "DNA_object_types.h" #include "DNA_sequence_types.h" -#include "BKE_depsgraph.h" - #include "RNA_access.h" } @@ -70,8 +68,7 @@ static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL; Depsgraph::Depsgraph() : root_node(NULL), - need_update(false), - layers(0) + need_update(false) { BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 1c9ba8c4cb1..bc017e0c72a 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -45,6 +45,7 @@ struct GHash; struct GSet; struct PointerRNA; struct PropertyRNA; +struct Scene; namespace DEG { @@ -160,12 +161,9 @@ struct Depsgraph { */ SpinLock lock; - /* Layers Visibility .................. */ - - /* Visible layers bitfield, used for skipping invisible objects updates. */ - unsigned int layers; - // XXX: additional stuff like eval contexts, mempools for allocating nodes from, etc. + + Scene *scene; /* XXX: We really shouldn't do that, but it's required for shader preview */ }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index f8bc8b9eb35..82be671236f 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -319,14 +319,13 @@ void DEG_add_collision_relations(DepsNodeHandle *handle, Scene *scene, Object *ob, Group *group, - int layer, unsigned int modifier_type, DEG_CollobjFilterFunction fn, bool dupli, const char *name) { unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli); + Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, modifier_type, dupli); for (unsigned int i = 0; i < numcollobj; i++) { Object *ob1 = collobjs[i]; @@ -381,7 +380,6 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, scene, ob, NULL, - eff->ob->lay, eModifierType_Collision, NULL, true, diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc index 85a0d336d28..62d591f65de 100644 --- a/source/blender/depsgraph/intern/depsgraph_eval.cc +++ b/source/blender/depsgraph/intern/depsgraph_eval.cc @@ -36,9 +36,6 @@ #include "BLI_ghash.h" extern "C" { -#include "DNA_scene_types.h" - -#include "BKE_depsgraph.h" #include "BKE_scene.h" } /* extern "C" */ @@ -52,43 +49,9 @@ extern "C" { #include "intern/depsgraph.h" -#ifdef WITH_LEGACY_DEPSGRAPH -static bool use_legacy_depsgraph = true; -#endif - /* Unfinished and unused, and takes quite some pre-processing time. */ #undef USE_EVAL_PRIORITY -bool DEG_depsgraph_use_legacy(void) -{ -#ifdef DISABLE_NEW_DEPSGRAPH - return true; -#elif defined(WITH_LEGACY_DEPSGRAPH) - return use_legacy_depsgraph; -#else - BLI_assert(!"Should not be used with new depsgraph"); - return false; -#endif -} - -void DEG_depsgraph_switch_to_legacy(void) -{ -#ifdef WITH_LEGACY_DEPSGRAPH - use_legacy_depsgraph = true; -#else - BLI_assert(!"Should not be used with new depsgraph"); -#endif -} - -void DEG_depsgraph_switch_to_new(void) -{ -#ifdef WITH_LEGACY_DEPSGRAPH - use_legacy_depsgraph = false; -#else - BLI_assert(!"Should not be used with new depsgraph"); -#endif -} - /* ****************** */ /* Evaluation Context */ @@ -127,22 +90,14 @@ void DEG_evaluate_on_refresh(EvaluationContext *eval_ctx, /* Update time on primary timesource. */ DEG::TimeSourceDepsNode *tsrc = deg_graph->find_time_source(); tsrc->cfra = BKE_scene_frame_get(scene); - unsigned int layers = deg_graph->layers; - /* XXX(sergey): This works around missing updates in temp scenes used - * by various scripts, but is weak and needs closer investigation. - */ - if (layers == 0) { - layers = scene->lay; - } - DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers); + DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph); } /* Frame-change happened for root scene that graph belongs to. */ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx, Main *bmain, Depsgraph *graph, - float ctime, - const unsigned int layers) + float ctime) { DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); /* Update time on primary timesource. */ @@ -151,7 +106,7 @@ void DEG_evaluate_on_framechange(EvaluationContext *eval_ctx, tsrc->tag_update(deg_graph); DEG::deg_graph_flush_updates(bmain, deg_graph); /* Perform recalculation updates. */ - DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph, layers); + DEG::deg_evaluate_on_refresh(eval_ctx, deg_graph); } bool DEG_needs_eval(Depsgraph *graph) diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index e58a7a32407..0661f24fb7b 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -33,13 +33,21 @@ #include "MEM_guardedalloc.h" extern "C" { +#include "BLI_math.h" +#include "BKE_anim.h" #include "BKE_idcode.h" +#include "BKE_layer.h" #include "BKE_main.h" } /* extern "C" */ +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" #include "intern/depsgraph_intern.h" +#include "util/deg_util_foreach.h" bool DEG_id_type_tagged(Main *bmain, short idtype) { @@ -68,3 +76,178 @@ short DEG_get_eval_flags_for_id(Depsgraph *graph, ID *id) return id_node->eval_flags; } + +Scene *DEG_get_scene(Depsgraph *graph) +{ + DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); + return deg_graph->scene; +} + +SceneLayer *DEG_get_scene_layer(Depsgraph *graph) +{ + Scene *scene = DEG_get_scene(graph); + if (scene) { + return BKE_scene_layer_context_active(scene); + } + return NULL; +} + +Object *DEG_get_object(Depsgraph * /*depsgraph*/, Object *ob) +{ + /* XXX TODO */ + return ob; +} + +/* ************************ DAG ITERATORS ********************* */ + +#define BASE_FLUSH_FLAGS (BASE_FROM_SET | BASE_FROMDUPLI) + +void DEG_objects_iterator_begin(BLI_Iterator *iter, DEGObjectsIteratorData *data) +{ + Depsgraph *graph = data->graph; + SceneLayer *scene_layer = DEG_get_scene_layer(graph); + + iter->data = data; + iter->valid = true; + + data->scene = DEG_get_scene(graph); + /* TODO(sergey): Make it in-place initilization of evaluation context. */ + data->eval_ctx = DEG_evaluation_context_new(DAG_EVAL_RENDER); + + /* TODO(sergey): It's really confusing to store pointer to a local data. */ + Base base = {(Base *)scene_layer->object_bases.first, NULL}; + data->base = &base; + + data->base_flag = ~(BASE_FLUSH_FLAGS); + + data->dupli_parent = NULL; + data->dupli_list = NULL; + data->dupli_object_next = NULL; + data->dupli_object_current = NULL; + + DEG_objects_iterator_next(iter); +} + +/** + * Temporary function to flush depsgraph until we get copy on write (CoW) + */ +static void deg_flush_base_flags_and_settings(Object *ob, Base *base, const int flag) +{ + ob->base_flag = (base->flag | BASE_FLUSH_FLAGS) & flag; + ob->base_collection_properties = base->collection_properties; + ob->base_selection_color = base->selcol; +} + +static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) +{ + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + while (data->dupli_object_next != NULL) { + DupliObject *dob = data->dupli_object_next; + Object *obd = dob->ob; + + data->dupli_object_next = data->dupli_object_next->next; + + /* Group duplis need to set ob matrices correct, for deform. so no_draw + * is part handled. + */ + if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) { + continue; + } + + if (obd->type == OB_MBALL) { + continue; + } + + data->dupli_object_current = dob; + + /* Temporary object to evaluate. */ + data->temp_dupli_object = *dob->ob; + copy_m4_m4(data->temp_dupli_object.obmat, dob->mat); + + deg_flush_base_flags_and_settings(&data->temp_dupli_object, + data->base, + data->base_flag | BASE_FROMDUPLI); + iter->current = &data->temp_dupli_object; + return true; + } + + return false; +} + +void DEG_objects_iterator_next(BLI_Iterator *iter) +{ + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + Base *base; + + if (data->dupli_list) { + if (deg_objects_dupli_iterator_next(iter)) { + return; + } + else { + free_object_duplilist(data->dupli_list); + data->dupli_parent = NULL; + data->dupli_list = NULL; + data->dupli_object_next = NULL; + data->dupli_object_current = NULL; + } + } + + base = data->base->next; + while (base != NULL) { + if ((base->flag & BASE_VISIBLED) != 0) { + Object *ob = DEG_get_object(data->graph, base->object); + iter->current = ob; + data->base = base; + + /* Make sure we have the base collection settings is already populated. + * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet + * Which usually means a missing call to DAG_id_tag_update(). */ + BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group)); + + /* Flushing depsgraph data. */ + deg_flush_base_flags_and_settings(ob, + base, + data->base_flag); + + if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (ob->transflag & OB_DUPLI)) { + data->dupli_parent = ob; + data->dupli_list = object_duplilist(data->eval_ctx, data->scene, ob); + data->dupli_object_next = (DupliObject *)data->dupli_list->first; + } + return; + } + base = base->next; + } + + /* Look for an object in the next set. */ + if ((data->flag & DEG_OBJECT_ITER_FLAG_SET) && data->scene->set) { + SceneLayer *scene_layer; + data->scene = data->scene->set; + data->base_flag = ~(BASE_SELECTED | BASE_SELECTABLED); + + /* For the sets we use the layer used for rendering. */ + scene_layer = BKE_scene_layer_render_active(data->scene); + + /* TODO(sergey): It's really confusing to store pointer to a local data. */ + Base base = {(Base *)scene_layer->object_bases.first, NULL}; + data->base = &base; + DEG_objects_iterator_next(iter); + return; + } + + iter->current = NULL; + iter->valid = false; +} + +void DEG_objects_iterator_end(BLI_Iterator *iter) +{ + DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data; + if (data->eval_ctx != NULL) { + DEG_evaluation_context_free(data->eval_ctx); + } + +#ifdef DEBUG + /* Force crash in case the iterator data is referenced and accessed down the line. (T51718) */ + memset(&data->temp_dupli_object, 0xFF, sizeof(data->temp_dupli_object)); +#endif +} diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 31b4bbc7950..a2b8a93ecda 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -49,6 +49,7 @@ extern "C" { #include "BKE_library.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_workspace.h" #define new new_ #include "BKE_screen.h" @@ -289,89 +290,13 @@ void DEG_ids_flush_tagged(Main *bmain) /* Update dependency graph when visible scenes/layers changes. */ void DEG_graph_on_visible_update(Main *bmain, Scene *scene) { + (void) bmain; DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph); - wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; - int old_layers = graph->layers; - if (wm != NULL) { - BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true); - graph->layers = 0; - for (wmWindow *win = (wmWindow *)wm->windows.first; - win != NULL; - win = (wmWindow *)win->next) - { - Scene *scene = win->screen->scene; - if (scene->id.tag & LIB_TAG_DOIT) { - graph->layers |= BKE_screen_visible_layers(win->screen, scene); - scene->id.tag &= ~LIB_TAG_DOIT; - } - } - } - else { - /* All the layers for background render for now. */ - graph->layers = (1 << 20) - 1; - } - if (old_layers != graph->layers) { - /* Tag all objects which becomes visible (or which becomes needed for dependencies) - * for recalc. - * - * This is mainly needed on file load only, after that updates of invisible objects - * will be stored in the pending list. - */ - GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash) - { - ID *id = id_node->id; - if ((id->tag & LIB_TAG_ID_RECALC_ALL) != 0 || - (id_node->layers & scene->lay_updated) == 0) - { - id_node->tag_update(graph); - } - /* A bit of magic: if object->recalc is set it means somebody tagged - * it for update. If corresponding ID recalc flags are zero it means - * graph has been evaluated after that and the recalc was skipped - * because of visibility check. - */ - if (GS(id->name) == ID_OB) { - Object *object = (Object *)id; - if ((id->tag & LIB_TAG_ID_RECALC_ALL) == 0 && - (object->recalc & OB_RECALC_ALL) != 0) - { - id_node->tag_update(graph); - DEG::ComponentDepsNode *anim_comp = - id_node->find_component(DEG::DEG_NODE_TYPE_ANIMATION); - if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) { - anim_comp->tag_update(graph); - } - } - } - } - GHASH_FOREACH_END(); - } - scene->lay_updated |= graph->layers; - /* Special trick to get local view to work. */ - LINKLIST_FOREACH (Base *, base, &scene->base) { - Object *object = base->object; - DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); - id_node->layers = 0; - } - LINKLIST_FOREACH (Base *, base, &scene->base) { - Object *object = base->object; - DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); - id_node->layers |= base->lay; - if (object == scene->camera) { - /* Camera should always be updated, it used directly by viewport. */ - id_node->layers |= (unsigned int)(-1); - } - } - DEG::deg_graph_build_flush_layers(graph); - LINKLIST_FOREACH (Base *, base, &scene->base) { - Object *object = base->object; - DEG::IDDepsNode *id_node = graph->find_id_node(&object->id); - GHASH_FOREACH_BEGIN(DEG::ComponentDepsNode *, comp, id_node->components) - { - id_node->layers |= comp->layers; - } - GHASH_FOREACH_END(); + GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash) + { + id_node->tag_update(graph); } + GHASH_FOREACH_END(); } void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time)) diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 77454cd85ec..612944dab6e 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -120,6 +120,10 @@ static const char *stringify_opcode(eDepsOperation_Code opcode) STRINGIFY_OPCODE(BONE_DONE); STRINGIFY_OPCODE(PSYS_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_INIT); + STRINGIFY_OPCODE(SCENE_LAYER_EVAL); + STRINGIFY_OPCODE(SCENE_LAYER_DONE); + case DEG_NUM_OPCODES: return "SpecialCase"; #undef STRINGIFY_OPCODE } diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index 0d857a8dc52..c72e93e30ab 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -129,6 +129,8 @@ typedef enum eDepsNode_Type { DEG_NODE_TYPE_SHADING, /* Cache Component */ DEG_NODE_TYPE_CACHE, + /* Component which contains all operations needed for layer collections evaluation. */ + DEG_NODE_TYPE_LAYER_COLLECTIONS, } eDepsNode_Type; /* Identifiers for common operations (as an enum). */ @@ -223,6 +225,11 @@ typedef enum eDepsOperation_Code { /* XXX: placeholder - Particle System eval */ DEG_OPCODE_PSYS_EVAL, + /* Collections ------------------------------------- */ + DEG_OPCODE_SCENE_LAYER_INIT, + DEG_OPCODE_SCENE_LAYER_EVAL, + DEG_OPCODE_SCENE_LAYER_DONE, + DEG_NUM_OPCODES, } eDepsOperation_Code; diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 98b10718404..15ad6b8054d 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -38,11 +38,6 @@ #include "BLI_task.h" #include "BLI_ghash.h" -extern "C" { -#include "BKE_depsgraph.h" -#include "BKE_global.h" -} /* extern "C" */ - #include "DEG_depsgraph.h" #include "atomic_ops.h" @@ -73,13 +68,11 @@ namespace DEG { static void schedule_children(TaskPool *pool, Depsgraph *graph, OperationDepsNode *node, - const unsigned int layers, const int thread_id); struct DepsgraphEvalState { EvaluationContext *eval_ctx; Depsgraph *graph; - unsigned int layers; }; static void deg_task_run_func(TaskPool *pool, @@ -127,39 +120,31 @@ static void deg_task_run_func(TaskPool *pool, } BLI_task_pool_delayed_push_begin(pool, thread_id); - schedule_children(pool, state->graph, node, state->layers, thread_id); + schedule_children(pool, state->graph, node, thread_id); BLI_task_pool_delayed_push_end(pool, thread_id); } typedef struct CalculatePengindData { Depsgraph *graph; - unsigned int layers; } CalculatePengindData; static void calculate_pending_func(void *data_v, int i) { CalculatePengindData *data = (CalculatePengindData *)data_v; Depsgraph *graph = data->graph; - unsigned int layers = data->layers; OperationDepsNode *node = graph->operations[i]; - IDDepsNode *id_node = node->owner->owner; node->num_links_pending = 0; node->scheduled = false; /* count number of inputs that need updates */ - if ((id_node->layers & layers) != 0 && - (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) - { + if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) { foreach (DepsRelation *rel, node->inlinks) { if (rel->from->type == DEG_NODE_TYPE_OPERATION && (rel->flag & DEPSREL_FLAG_CYCLIC) == 0) { OperationDepsNode *from = (OperationDepsNode *)rel->from; - IDDepsNode *id_from_node = from->owner->owner; - if ((id_from_node->layers & layers) != 0 && - (from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) - { + if ((from->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) { ++node->num_links_pending; } } @@ -167,13 +152,12 @@ static void calculate_pending_func(void *data_v, int i) } } -static void calculate_pending_parents(Depsgraph *graph, unsigned int layers) +static void calculate_pending_parents(Depsgraph *graph) { const int num_operations = graph->operations.size(); const bool do_threads = num_operations > 256; CalculatePengindData data; data.graph = graph; - data.layers = layers; BLI_task_parallel_range(0, num_operations, &data, @@ -212,15 +196,11 @@ static void calculate_eval_priority(OperationDepsNode *node) * dec_parents: Decrement pending parents count, true when child nodes are * scheduled after a task has been completed. */ -static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers, +static void schedule_node(TaskPool *pool, Depsgraph *graph, OperationDepsNode *node, bool dec_parents, const int thread_id) { - unsigned int id_layers = node->owner->owner->layers; - - if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0 && - (id_layers & layers) != 0) - { + if ((node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0) { if (dec_parents) { BLI_assert(node->num_links_pending > 0); atomic_sub_and_fetch_uint32(&node->num_links_pending, 1); @@ -232,7 +212,7 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers, if (!is_scheduled) { if (node->is_noop()) { /* skip NOOP node, schedule children right away */ - schedule_children(pool, graph, node, layers, thread_id); + schedule_children(pool, graph, node, thread_id); } else { /* children are scheduled once this task is completed */ @@ -248,19 +228,16 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers, } } -static void schedule_graph(TaskPool *pool, - Depsgraph *graph, - const unsigned int layers) +static void schedule_graph(TaskPool *pool, Depsgraph *graph) { foreach (OperationDepsNode *node, graph->operations) { - schedule_node(pool, graph, layers, node, false, 0); + schedule_node(pool, graph, node, false, 0); } } static void schedule_children(TaskPool *pool, Depsgraph *graph, OperationDepsNode *node, - const unsigned int layers, const int thread_id) { foreach (DepsRelation *rel, node->outlinks) { @@ -272,7 +249,6 @@ static void schedule_children(TaskPool *pool, } schedule_node(pool, graph, - layers, child, (rel->flag & DEPSREL_FLAG_CYCLIC) == 0, thread_id); @@ -287,8 +263,7 @@ static void schedule_children(TaskPool *pool, * \note Time sources should be all valid! */ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, - Depsgraph *graph, - const unsigned int layers) + Depsgraph *graph) { /* Generate base evaluation context, upon which all the others are derived. */ // TODO: this needs both main and scene access... @@ -298,11 +273,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, return; } - DEG_DEBUG_PRINTF("%s: layers:%u, graph->layers:%u\n", - __func__, - layers, - graph->layers); - /* Set time for the current graph evaluation context. */ TimeSourceDepsNode *time_src = graph->find_time_source(); eval_ctx->ctime = time_src->cfra; @@ -311,7 +281,6 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, DepsgraphEvalState state; state.eval_ctx = eval_ctx; state.graph = graph; - state.layers = layers; TaskScheduler *task_scheduler; bool need_free_scheduler; @@ -327,7 +296,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state); - calculate_pending_parents(graph, layers); + calculate_pending_parents(graph); /* Clear tags. */ foreach (OperationDepsNode *node, graph->operations) { @@ -343,7 +312,7 @@ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, DepsgraphDebug::eval_begin(eval_ctx); - schedule_graph(task_pool, graph, layers); + schedule_graph(task_pool, graph); BLI_task_pool_work_and_wait(task_pool); BLI_task_pool_free(task_pool); diff --git a/source/blender/depsgraph/intern/eval/deg_eval.h b/source/blender/depsgraph/intern/eval/deg_eval.h index 49c0379939e..576ab89dec1 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.h +++ b/source/blender/depsgraph/intern/eval/deg_eval.h @@ -46,7 +46,6 @@ struct Depsgraph; * \note Time sources should be all valid! */ void deg_evaluate_on_refresh(EvaluationContext *eval_ctx, - Depsgraph *graph, - const unsigned int layers); + Depsgraph *graph); } // namespace DEG diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 9989afff48c..bb56689cf3f 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -172,6 +172,7 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) case DEG_NODE_TYPE_ID_REF: case DEG_NODE_TYPE_PARAMETERS: case DEG_NODE_TYPE_SEQUENCER: + case DEG_NODE_TYPE_LAYER_COLLECTIONS: /* Ignore, does not translate to object component. */ break; case DEG_NODE_TYPE_ANIMATION: @@ -190,6 +191,9 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph) object->recalc |= OB_RECALC_DATA; break; } + + /* TODO : replace with more granular flags */ + object->deg_update_flag |= DEG_RUNTIME_DATA_UPDATE; } } diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index 6785abbeb22..569ac26633d 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -189,14 +189,8 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) /* Store ID-pointer. */ BLI_assert(id != NULL); this->id = (ID *)id; - this->layers = (1 << 20) - 1; this->eval_flags = 0; - /* For object we initialize layers to layer from base. */ - if (GS(id->name) == ID_OB) { - this->layers = 0; - } - components = BLI_ghash_new(id_deps_node_hash_key, id_deps_node_hash_key_cmp, "Depsgraph id components hash"); diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index 354f0fd6857..d0687dbb5eb 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -173,9 +173,6 @@ struct IDDepsNode : public DepsNode { /* Hash to make it faster to look up components. */ GHash *components; - /* Layers of this node with accumulated layers of it's output relations. */ - unsigned int layers; - /* Additional flags needed for scene evaluation. * TODO(sergey): Only needed for until really granular updates * of all the entities. diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 4a7667c485c..4a99985d4c1 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -123,8 +123,7 @@ static void comp_node_hash_value_free(void *value_v) ComponentDepsNode::ComponentDepsNode() : entry_operation(NULL), - exit_operation(NULL), - layers(0) + exit_operation(NULL) { operations_map = BLI_ghash_new(comp_node_hash_key, comp_node_hash_key_cmp, @@ -157,10 +156,7 @@ string ComponentDepsNode::identifier() const char typebuf[16]; sprintf(typebuf, "(%d)", type); - char layers[16]; - sprintf(layers, "%u", this->layers); - - return string(typebuf) + name + " : " + idname + " (Layers: " + layers + ")"; + return string(typebuf) + name + " : " + idname; } OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const @@ -405,6 +401,10 @@ static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING; DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEG_NODE_TYPE_CACHE, "Cache Component"); static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE; +/* Layer Collections Defines ============================ */ + +DEG_DEPSNODE_DEFINE(LayerCollectionsDepsNode, DEG_NODE_TYPE_LAYER_COLLECTIONS, "Layer Collections Component"); +static DepsNodeFactoryImpl<LayerCollectionsDepsNode> DNTI_LAYER_COLLECTIONS; /* Node Types Register =================================== */ @@ -424,6 +424,8 @@ void deg_register_component_depsnodes() deg_register_node_typeinfo(&DNTI_SHADING); deg_register_node_typeinfo(&DNTI_CACHE); + + deg_register_node_typeinfo(&DNTI_LAYER_COLLECTIONS); } } // namespace DEG diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index f476d8ff202..c358c510ae3 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -151,9 +151,6 @@ struct ComponentDepsNode : public DepsNode { OperationDepsNode *exit_operation; // XXX: a poll() callback to check if component's first node can be started? - - /* Temporary bitmask, used during graph construction. */ - unsigned int layers; }; /* ---------------------------------------- */ @@ -207,6 +204,10 @@ struct CacheComponentDepsNode : public ComponentDepsNode { DEG_DEPSNODE_DECLARE; }; +struct LayerCollectionsDepsNode : public ComponentDepsNode { + DEG_DEPSNODE_DECLARE; +}; + void deg_register_component_depsnodes(); |