Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 23 Apr 2018 12:55:38 +0000 (14:55 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 23 Apr 2018 12:55:38 +0000 (14:55 +0200)
1  2 
source/blender/depsgraph/intern/depsgraph.cc

index a87358187f26902d2e7c3d3444a9a5de8cfb6e9d,34fb20ee2bace1f9ee73b21e37f2f54ed0a1f80a..c90279b0e90d1bd9050558e4f024c82640bfffb1
@@@ -48,9 -48,9 +48,9 @@@ extern "C" 
  #include "DNA_object_types.h"
  #include "DNA_sequence_types.h"
  
 -#include "BKE_depsgraph.h"
 -
  #include "RNA_access.h"
 +
 +#include "BKE_scene.h"
  }
  
  #include <algorithm>
@@@ -58,8 -58,6 +58,8 @@@
  
  #include "DEG_depsgraph.h"
  
 +#include "intern/eval/deg_eval_copy_on_write.h"
 +
  #include "intern/nodes/deg_node.h"
  #include "intern/nodes/deg_node_component.h"
  #include "intern/nodes/deg_node_id.h"
  #include "intern/depsgraph_intern.h"
  #include "util/deg_util_foreach.h"
  
 +static bool use_copy_on_write = false;
 +
 +bool DEG_depsgraph_use_copy_on_write(void)
 +{
 +      return use_copy_on_write;
 +}
 +
 +void DEG_depsgraph_enable_copy_on_write(void)
 +{
 +      use_copy_on_write = true;
 +}
 +
  namespace DEG {
  
  static DEG_EditorUpdateIDCb deg_editor_update_id_cb = NULL;
  static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
 -static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
  
  /* TODO(sergey): Find a better place for this. */
  template <typename T>
@@@ -94,15 -81,10 +94,15 @@@ static void remove_from_vector(vector<T
                      vector->end());
  }
  
 -Depsgraph::Depsgraph()
 +Depsgraph::Depsgraph(Scene *scene,
 +                     ViewLayer *view_layer,
 +                     eEvaluationMode mode)
    : time_source(NULL),
 -    need_update(false),
 -    layers(0)
 +    need_update(true),
 +    scene(scene),
 +    view_layer(view_layer),
 +    mode(mode),
 +    ctime(BKE_scene_frame_get(scene))
  {
        BLI_spin_init(&lock);
        id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
@@@ -232,10 -214,11 +232,15 @@@ static bool pointer_to_component_node_c
                *subdata = seq->name; // xxx?
                return true;
        }
 +      else if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
 +              *type = DEG_NODE_TYPE_SHADING;
 +              return true;
 +      }
+       else if (ptr->type == &RNA_Curve) {
+               *id = (ID *)ptr->id.data;
+               *type = DEG_NODE_TYPE_GEOMETRY;
+               return true;
+       }
        if (prop != NULL) {
                /* All unknown data effectively falls under "parameter evaluation". */
                if (RNA_property_is_idprop(prop)) {
@@@ -291,6 -274,12 +296,6 @@@ DepsNode *Depsgraph::find_node_from_poi
  
  /* Node Management ---------------------------- */
  
 -static void id_node_deleter(void *value)
 -{
 -      IDDepsNode *id_node = reinterpret_cast<IDDepsNode *>(value);
 -      OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
 -}
 -
  TimeSourceDepsNode *Depsgraph::add_time_source()
  {
        if (time_source == NULL) {
@@@ -310,19 -299,13 +315,19 @@@ IDDepsNode *Depsgraph::find_id_node(con
        return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id));
  }
  
 -IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
 +IDDepsNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint)
  {
 +      BLI_assert((id->tag & LIB_TAG_COPY_ON_WRITE) == 0);
        IDDepsNode *id_node = find_id_node(id);
        if (!id_node) {
                DepsNodeFactory *factory = deg_type_get_factory(DEG_NODE_TYPE_ID_REF);
 -              id_node = (IDDepsNode *)factory->create_node(id, "", name);
 -              /* register */
 +              id_node = (IDDepsNode *)factory->create_node(id, "", id->name);
 +              id_node->init_copy_on_write(id_cow_hint);
 +              /* Register node in ID hash.
 +               *
 +               * NOTE: We address ID nodes by the original ID pointer they are
 +               * referencing to.
 +               */
                BLI_ghash_insert(id_hash, id, id_node);
                id_nodes.push_back(id_node);
        }
  
  void Depsgraph::clear_id_nodes()
  {
 -      BLI_ghash_clear(id_hash, NULL, id_node_deleter);
 +      /* Free memory used by ID nodes. */
 +      if (use_copy_on_write) {
 +              /* Stupid workaround to ensure we free IDs in a proper order. */
 +              foreach (IDDepsNode *id_node, id_nodes) {
 +                      if (id_node->id_cow == NULL) {
 +                              /* This means builder "stole" ownership of the copy-on-written
 +                               * datablock for her own dirty needs.
 +                               */
 +                              continue;
 +                      }
 +                      if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
 +                              continue;
 +                      }
 +                      const ID_Type id_type = GS(id_node->id_cow->name);
 +                      if (id_type != ID_PA) {
 +                              id_node->destroy();
 +                      }
 +              }
 +      }
 +      foreach (IDDepsNode *id_node, id_nodes) {
 +              OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
 +      }
 +      /* Clear containers. */
 +      BLI_ghash_clear(id_hash, NULL, NULL);
        id_nodes.clear();
  }
  
@@@ -379,7 -339,7 +384,7 @@@ DepsRelation *Depsgraph::add_new_relati
        if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
                IDDepsNode *id_to = to->owner->owner;
                IDDepsNode *id_from = from->owner->owner;
 -              if (id_to != id_from && (id_to->id->recalc & ID_RECALC_ALL)) {
 +              if (id_to != id_from && (id_to->id_orig->recalc & ID_RECALC_ALL)) {
                        if ((id_from->eval_flags & DAG_EVAL_NEED_CPU) == 0) {
                                id_from->tag_update(this);
                                id_from->eval_flags |= DAG_EVAL_NEED_CPU;
@@@ -473,9 -433,9 +478,9 @@@ void DepsRelation::unlink(
  void Depsgraph::add_entry_tag(OperationDepsNode *node)
  {
        /* Sanity check. */
 -      if (!node)
 +      if (node == NULL) {
                return;
 -
 +      }
        /* Add to graph-level set of directly modified nodes to start searching from.
         * NOTE: this is necessary since we have several thousand nodes to play with...
         */
@@@ -491,46 -451,17 +496,46 @@@ void Depsgraph::clear_all_nodes(
        }
  }
  
 -void deg_editors_id_update(Main *bmain, ID *id)
 +ID *Depsgraph::get_cow_id(const ID *id_orig) const
 +{
 +      IDDepsNode *id_node = find_id_node(id_orig);
 +      if (id_node == NULL) {
 +              /* This function is used from places where we expect ID to be either
 +               * already a copy-on-write version or have a corresponding copy-on-write
 +               * version.
 +               *
 +               * We try to enforce that in debug builds, for for release we play a bit
 +               * safer game here.
 +               */
 +              if ((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0) {
 +                      /* TODO(sergey): This is nice sanity check to have, but it fails
 +                       * in following situations:
 +                       *
 +                       * - Material has link to texture, which is not needed by new
 +                       *   shading system and hence can be ignored at construction.
 +                       * - Object or mesh has material at a slot which is not used (for
 +                       *   example, object has material slot by materials are set to
 +                       *   object data).
 +                       */
 +                      // BLI_assert(!"Request for non-existing copy-on-write ID");
 +              }
 +              return (ID *)id_orig;
 +      }
 +      return id_node->id_cow;
 +}
 +
 +void deg_editors_id_update(const DEGEditorUpdateContext *update_ctx, ID *id)
  {
        if (deg_editor_update_id_cb != NULL) {
 -              deg_editor_update_id_cb(bmain, id);
 +              deg_editor_update_id_cb(update_ctx, id);
        }
  }
  
 -void deg_editors_scene_update(Main *bmain, Scene *scene, bool updated)
 +void deg_editors_scene_update(const DEGEditorUpdateContext *update_ctx,
 +                              bool updated)
  {
        if (deg_editor_update_scene_cb != NULL) {
 -              deg_editor_update_scene_cb(bmain, scene, updated);
 +              deg_editor_update_scene_cb(update_ctx, updated);
        }
  }
  
@@@ -565,14 -496,9 +570,14 @@@ string deg_color_end(void
  /* Public Graph API */
  
  /* Initialize a new Depsgraph */
 -Depsgraph *DEG_graph_new()
 +Depsgraph *DEG_graph_new(Scene *scene,
 +                         ViewLayer *view_layer,
 +                         eEvaluationMode mode)
  {
 -      DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph);
 +      DEG::Depsgraph *deg_depsgraph = OBJECT_GUARDED_NEW(DEG::Depsgraph,
 +                                                         scene,
 +                                                         view_layer,
 +                                                         mode);
        return reinterpret_cast<Depsgraph *>(deg_depsgraph);
  }
  
@@@ -586,10 -512,19 +591,10 @@@ void DEG_graph_free(Depsgraph *graph
  
  /* Set callbacks which are being called when depsgraph changes. */
  void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func,
 -                               DEG_EditorUpdateSceneCb scene_func,
 -                               DEG_EditorUpdateScenePreCb scene_pre_func)
 +                               DEG_EditorUpdateSceneCb scene_func)
  {
        DEG::deg_editor_update_id_cb = id_func;
        DEG::deg_editor_update_scene_cb = scene_func;
 -      DEG::deg_editor_update_scene_pre_cb = scene_pre_func;
 -}
 -
 -void DEG_editors_update_pre(Main *bmain, Scene *scene, bool time)
 -{
 -      if (DEG::deg_editor_update_scene_pre_cb != NULL) {
 -              DEG::deg_editor_update_scene_pre_cb(bmain, scene, time);
 -      }
  }
  
  /* Evaluation and debug */