Merge branch 'master' into blender2.8
[blender.git] / source / blender / depsgraph / intern / depsgraph_tag.cc
index f00bce29f642582dc920208f44ffd1cdb04b538b..7c048751869ea139e6f144c0b693a122cc31c33d 100644 (file)
@@ -54,11 +54,14 @@ extern "C" {
 #include "DEG_depsgraph.h"
 } /* extern "C" */
 
-#include "depsgraph_debug.h"
-#include "depsnode.h"
-#include "depsnode_component.h"
-#include "depsnode_operation.h"
-#include "depsgraph_intern.h"
+#include "intern/eval/deg_eval_flush.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 "util/deg_util_foreach.h"
 
 /* *********************** */
 /* Update Tagging/Flushing */
@@ -126,19 +129,21 @@ void lib_id_recalc_tag_flag(Main *bmain, ID *id, int flag)
  */
 void DEG_graph_id_tag_update(Main *bmain, Depsgraph *graph, ID *id)
 {
-       IDDepsNode *node = graph->find_id_node(id);
+       DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+       DEG::IDDepsNode *node = deg_graph->find_id_node(id);
        lib_id_recalc_tag(bmain, id);
        if (node != NULL) {
-               node->tag_update(graph);
+               node->tag_update(deg_graph);
        }
 }
 
 /* Tag nodes related to a specific piece of data */
 void DEG_graph_data_tag_update(Depsgraph *graph, const PointerRNA *ptr)
 {
-       DepsNode *node = graph->find_node_from_pointer(ptr, NULL);
-       if (node) {
-               node->tag_update(graph);
+       DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+       DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, NULL);
+       if (node != NULL) {
+               node->tag_update(deg_graph);
        }
        else {
                printf("Missing node in %s\n", __func__);
@@ -151,9 +156,10 @@ void DEG_graph_property_tag_update(Depsgraph *graph,
                                    const PointerRNA *ptr,
                                    const PropertyRNA *prop)
 {
-       DepsNode *node = graph->find_node_from_pointer(ptr, prop);
-       if (node) {
-               node->tag_update(graph);
+       DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
+       DEG::DepsNode *node = deg_graph->find_node_from_pointer(ptr, prop);
+       if (node != NULL) {
+               node->tag_update(deg_graph);
        }
        else {
                printf("Missing node in %s\n", __func__);
@@ -223,131 +229,6 @@ void DEG_id_type_tag(Main *bmain, short idtype)
        bmain->id_tag_update[((unsigned char *)&idtype)[0]] = 1;
 }
 
-/* Update Flushing ---------------------------------- */
-
-/* FIFO queue for tagged nodes that need flushing */
-/* XXX This may get a dedicated implementation later if needed - lukas */
-typedef std::queue<OperationDepsNode *> FlushQueue;
-
-static void flush_init_func(void *data_v, int i)
-{
-       /* ID node's done flag is used to avoid multiple editors update
-        * for the same ID.
-        */
-       Depsgraph *graph = (Depsgraph *)data_v;
-       OperationDepsNode *node = graph->operations[i];
-       IDDepsNode *id_node = node->owner->owner;
-       id_node->done = 0;
-       node->scheduled = false;
-       node->owner->flags &= ~DEPSCOMP_FULLY_SCHEDULED;
-}
-
-/* Flush updates from tagged nodes outwards until all affected nodes are tagged. */
-void DEG_graph_flush_updates(Main *bmain, Depsgraph *graph)
-{
-       /* sanity check */
-       if (graph == NULL)
-               return;
-
-       /* Nothing to update, early out. */
-       if (graph->entry_tags.size() == 0) {
-               return;
-       }
-
-       /* TODO(sergey): With a bit of flag magic we can get rid of this
-        * extra loop.
-        */
-       const int num_operations = graph->operations.size();
-       const bool do_threads = num_operations > 256;
-       BLI_task_parallel_range(0, num_operations, graph, flush_init_func, do_threads);
-
-       FlushQueue queue;
-       /* Starting from the tagged "entry" nodes, flush outwards... */
-       /* NOTE: Also need to ensure that for each of these, there is a path back to
-        *       root, or else they won't be done.
-        * NOTE: Count how many nodes we need to handle - entry nodes may be
-        *       component nodes which don't count for this purpose!
-        */
-       for (Depsgraph::EntryTags::const_iterator it = graph->entry_tags.begin();
-            it != graph->entry_tags.end();
-            ++it)
-       {
-               OperationDepsNode *node = *it;
-               IDDepsNode *id_node = node->owner->owner;
-               queue.push(node);
-               if (id_node->done == 0) {
-                       deg_editors_id_update(bmain, id_node->id);
-                       id_node->done = 1;
-               }
-               node->scheduled = true;
-       }
-
-       while (!queue.empty()) {
-               OperationDepsNode *node = queue.front();
-               queue.pop();
-
-               IDDepsNode *id_node = node->owner->owner;
-               lib_id_recalc_tag(bmain, id_node->id);
-               /* TODO(sergey): For until we've got proper data nodes in the graph. */
-               lib_id_recalc_data_tag(bmain, id_node->id);
-
-               ID *id = id_node->id;
-               /* This code is used to preserve those areas which does direct
-                * object update,
-                *
-                * Plus it ensures visibility changes and relations and layers
-                * visibility update has proper flags to work with.
-                */
-               if (GS(id->name) == ID_OB) {
-                       Object *object = (Object *)id;
-                       ComponentDepsNode *comp_node = node->owner;
-                       if (comp_node->type == DEPSNODE_TYPE_ANIMATION) {
-                               object->recalc |= OB_RECALC_TIME;
-                       }
-                       else if (comp_node->type == DEPSNODE_TYPE_TRANSFORM) {
-                               object->recalc |= OB_RECALC_OB;
-                       }
-                       else {
-                               object->recalc |= OB_RECALC_DATA;
-                       }
-               }
-
-               /* Flush to nodes along links... */
-               for (OperationDepsNode::Relations::const_iterator it = node->outlinks.begin();
-                    it != node->outlinks.end();
-                    ++it)
-               {
-                       DepsRelation *rel = *it;
-                       OperationDepsNode *to_node = (OperationDepsNode *)rel->to;
-                       if (to_node->scheduled == false) {
-                               to_node->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
-                               queue.push(to_node);
-                               to_node->scheduled = true;
-                               if (id_node->done == 0) {
-                                       deg_editors_id_update(bmain, id_node->id);
-                                       id_node->done = 1;
-                               }
-                       }
-               }
-
-               /* TODO(sergey): For until incremental updates are possible
-                * witin a component at least we tag the whole component
-                * for update.
-                */
-               ComponentDepsNode *component = node->owner;
-               if ((component->flags & DEPSCOMP_FULLY_SCHEDULED) == 0) {
-                       for (ComponentDepsNode::OperationMap::iterator it = component->operations.begin();
-                            it != node->owner->operations.end();
-                            ++it)
-                       {
-                               OperationDepsNode *op = it->second;
-                               op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
-                       }
-                       component->flags |= DEPSCOMP_FULLY_SCHEDULED;
-               }
-       }
-}
-
 /* Recursively push updates out to all nodes dependent on this,
  * until all affected are tagged and/or scheduled up for eval
  */
@@ -359,34 +240,17 @@ void DEG_ids_flush_tagged(Main *bmain)
        {
                /* TODO(sergey): Only visible scenes? */
                if (scene->depsgraph != NULL) {
-                       DEG_graph_flush_updates(bmain, scene->depsgraph);
+                       DEG::deg_graph_flush_updates(
+                               bmain,
+                               reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph));
                }
        }
 }
 
-static void graph_clear_func(void *data_v, int i)
-{
-       Depsgraph *graph = (Depsgraph *)data_v;
-       OperationDepsNode *node = graph->operations[i];
-       /* Clear node's "pending update" settings. */
-       node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE);
-}
-
-/* Clear tags from all operation nodes. */
-void DEG_graph_clear_tags(Depsgraph *graph)
-{
-       /* Go over all operation nodes, clearing tags. */
-       const int num_operations = graph->operations.size();
-       const bool do_threads = num_operations > 256;
-       BLI_task_parallel_range(0, num_operations, graph, graph_clear_func, do_threads);
-       /* Clear any entry tags which haven't been flushed. */
-       graph->entry_tags.clear();
-}
-
 /* Update dependency graph when visible scenes/layers changes. */
 void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
 {
-       Depsgraph *graph = scene->depsgraph;
+       DEG::Depsgraph *graph = reinterpret_cast<DEG::Depsgraph *>(scene->depsgraph);
        wmWindowManager *wm = (wmWindowManager *)bmain->wm.first;
        int old_layers = graph->layers;
        if (wm != NULL) {
@@ -414,11 +278,8 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
                 * This is mainly needed on file load only, after that updates of invisible objects
                 * will be stored in the pending list.
                 */
-               for (Depsgraph::IDNodeMap::const_iterator it = graph->id_hash.begin();
-                    it != graph->id_hash.end();
-                    ++it)
+               GHASH_FOREACH_BEGIN(DEG::IDDepsNode *, id_node, graph->id_hash)
                {
-                       IDDepsNode *id_node = it->second;
                        ID *id = id_node->id;
                        if ((id->tag & LIB_TAG_ID_RECALC_ALL) != 0 ||
                            (id_node->layers & scene->lay_updated) == 0)
@@ -436,14 +297,15 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
                                    (object->recalc & OB_RECALC_ALL) != 0)
                                {
                                        id_node->tag_update(graph);
-                                       ComponentDepsNode *anim_comp =
-                                               id_node->find_component(DEPSNODE_TYPE_ANIMATION);
+                                       DEG::ComponentDepsNode *anim_comp =
+                                               id_node->find_component(DEG::DEPSNODE_TYPE_ANIMATION);
                                        if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) {
                                                anim_comp->tag_update(graph);
                                        }
                                }
                        }
                }
+               GHASH_FOREACH_END();
        }
        scene->lay_updated |= graph->layers;
 }
@@ -484,7 +346,7 @@ void DEG_ids_check_recalc(Main *bmain, Scene *scene, bool time)
                }
        }
 
-       deg_editors_scene_update(bmain, scene, (updated || time));
+       DEG::deg_editors_scene_update(bmain, scene, (updated || time));
 }
 
 void DEG_ids_clear_recalc(Main *bmain)