Blender  V3.3
deg_node_id.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
9 
10 #include <cstdio>
11 #include <cstring> /* required for STREQ later on. */
12 
13 #include "BLI_string.h"
14 #include "BLI_utildefines.h"
15 
16 #include "DNA_ID.h"
17 #include "DNA_anim_types.h"
18 
19 #include "BKE_lib_id.h"
20 
21 #include "DEG_depsgraph.h"
22 
27 
28 namespace blender::deg {
29 
31 {
32  switch (linked_state) {
34  return "INDIRECTLY";
36  return "VIA_SET";
38  return "DIRECTLY";
39  }
40  BLI_assert_msg(0, "Unhandled linked state, should never happen.");
41  return "UNKNOWN";
42 }
43 
45 {
46 }
47 
49 {
50  return type == other.type && STREQ(name, other.name);
51 }
52 
54 {
55  const int type_as_int = static_cast<int>(type);
58 }
59 
60 void IDNode::init(const ID *id, const char *UNUSED(subdata))
61 {
62  BLI_assert(id != nullptr);
63  /* Store ID-pointer. */
64  id_type = GS(id->name);
65  id_orig = (ID *)id;
66  id_orig_session_uuid = id->session_uuid;
67  eval_flags = 0;
72  is_visible_on_build = true;
73  is_enabled_on_eval = true;
75  has_base = false;
76  is_user_modified = false;
78 
81 }
82 
83 void IDNode::init_copy_on_write(ID *id_cow_hint)
84 {
85  /* Create pointer as early as possible, so we can use it for function
86  * bindings. Rest of data we'll be copying to the new datablock when
87  * it is actually needed. */
88  if (id_cow_hint != nullptr) {
89  // BLI_assert(deg_copy_on_write_is_needed(id_orig));
91  id_cow = id_cow_hint;
92  }
93  else {
94  id_cow = id_orig;
95  }
96  }
100  "Create shallow copy for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
102  }
103  else {
104  id_cow = id_orig;
105  }
106 }
107 
108 /* Free 'id' node. */
110 {
111  destroy();
112 }
113 
115 {
116  if (id_orig == nullptr) {
117  return;
118  }
119 
120  for (ComponentNode *comp_node : components.values()) {
121  delete comp_node;
122  }
123 
124  /* Free memory used by this CoW ID. */
125  if (!ELEM(id_cow, id_orig, nullptr)) {
127  MEM_freeN(id_cow);
128  id_cow = nullptr;
129  DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
130  }
131 
132  /* Tag that the node is freed. */
133  id_orig = nullptr;
134 }
135 
136 string IDNode::identifier() const
137 {
138  char orig_ptr[24], cow_ptr[24];
139  BLI_snprintf(orig_ptr, sizeof(orig_ptr), "%p", id_orig);
140  BLI_snprintf(cow_ptr, sizeof(cow_ptr), "%p", id_cow);
141  return string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr +
142  ", eval: " + cow_ptr + ", is_visible_on_build " +
143  (is_visible_on_build ? "true" : "false") + ")";
144 }
145 
147 {
148  ComponentIDKey key(type, name);
149  return components.lookup_default(key, nullptr);
150 }
151 
153 {
154  ComponentNode *comp_node = find_component(type, name);
155  if (!comp_node) {
157  comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
158 
159  /* Register. */
160  ComponentIDKey key(type, name);
161  components.add_new(key, comp_node);
162  comp_node->owner = this;
163  }
164  return comp_node;
165 }
166 
168 {
169  for (ComponentNode *comp_node : components.values()) {
170  /* Relations update does explicit animation update when needed. Here we ignore animation
171  * component to avoid loss of possible unkeyed changes. */
172  if (comp_node->type == NodeType::ANIMATION && source == DEG_UPDATE_SOURCE_RELATIONS) {
173  continue;
174  }
175  comp_node->tag_update(graph, source);
176  }
177 }
178 
180 {
181  /* Finalize build of all components. */
182  for (ComponentNode *comp_node : components.values()) {
183  comp_node->finalize_build(graph);
184  }
186 }
187 
189 {
191  for (ComponentNode *comp_node : components.values()) {
192  if (comp_node->possibly_affects_visible_id) {
193  const int component_type_as_int = static_cast<int>(comp_node->type);
194  BLI_assert(component_type_as_int < 64);
195  result |= (1ULL << component_type_as_int);
196  }
197  }
198  return result;
199 }
200 
201 } // namespace blender::deg
void * BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1039
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
unsigned int BLI_ghashutil_uinthash(unsigned int key)
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
ID and Library types, which are fundamental for sdna.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Depsgraph * graph
#define DEG_COW_PRINT(format,...)
#define GS(x)
Definition: iris.c:225
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
bool deg_copy_on_write_is_needed(const ID *id_orig)
const char * linkedStateAsString(eDepsNode_LinkedState_Type linked_state)
Definition: deg_node_id.cc:30
DepsNodeFactory * type_get_factory(const NodeType type)
void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig)
uint64_t IDComponentsMask
Definition: deg_node_id.h:17
eDepsNode_LinkedState_Type
Definition: deg_node_id.h:23
@ DEG_ID_LINKED_INDIRECTLY
Definition: deg_node_id.h:25
@ DEG_ID_LINKED_VIA_SET
Definition: deg_node_id.h:27
@ DEG_ID_LINKED_DIRECTLY
Definition: deg_node_id.h:29
void deg_free_copy_on_write_datablock(ID *id_cow)
@ DEG_UPDATE_SOURCE_RELATIONS
const char * nodeTypeAsString(NodeType type)
Definition: deg_node.cc:39
unsigned __int64 uint64_t
Definition: stdint.h:90
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
virtual Node * create_node(const ID *id, const char *subdata, const char *name) const =0
bool operator==(const ComponentIDKey &other) const
Definition: deg_node_id.cc:48
ComponentIDKey(NodeType type, const char *name="")
Definition: deg_node_id.cc:44
IDComponentsMask previously_visible_components_mask
Definition: deg_node_id.h:127
void init_copy_on_write(ID *id_cow_hint=nullptr)
Definition: deg_node_id.cc:83
DEGCustomDataMeshMasks customdata_masks
Definition: deg_node_id.h:89
DEGCustomDataMeshMasks previous_customdata_masks
Definition: deg_node_id.h:90
ComponentNode * add_component(NodeType type, const char *name="")
Definition: deg_node_id.cc:152
virtual string identifier() const override
Definition: deg_node_id.cc:136
IDComponentsMask visible_components_mask
Definition: deg_node_id.h:126
bool is_collection_fully_expanded
Definition: deg_node_id.h:112
virtual void init(const ID *id, const char *subdata) override
Definition: deg_node_id.cc:60
Map< ComponentIDKey, ComponentNode * > components
Definition: deg_node_id.h:80
IDComponentsMask get_visible_components_mask() const
Definition: deg_node_id.cc:188
void finalize_build(Depsgraph *graph)
Definition: deg_node_id.cc:179
ComponentNode * find_component(NodeType type, const char *name="") const
Definition: deg_node_id.cc:146
eDepsNode_LinkedState_Type linked_state
Definition: deg_node_id.h:92
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
Definition: deg_node_id.cc:167
uint32_t previous_eval_flags
Definition: deg_node_id.h:86