Blender  V2.93
deg_node_id.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19 
25 
26 #include <cstdio>
27 #include <cstring> /* required for STREQ later on. */
28 
29 #include "BLI_string.h"
30 #include "BLI_utildefines.h"
31 
32 #include "DNA_ID.h"
33 #include "DNA_anim_types.h"
34 
35 #include "BKE_lib_id.h"
36 
37 #include "DEG_depsgraph.h"
38 
43 
44 namespace blender::deg {
45 
47 {
48  switch (linked_state) {
50  return "INDIRECTLY";
52  return "VIA_SET";
54  return "DIRECTLY";
55  }
56  BLI_assert(!"Unhandled linked state, should never happen.");
57  return "UNKNOWN";
58 }
59 
61 {
62 }
63 
65 {
66  return type == other.type && STREQ(name, other.name);
67 }
68 
70 {
71  const int type_as_int = static_cast<int>(type);
74 }
75 
76 /* Initialize 'id' node - from pointer data given. */
77 void IDNode::init(const ID *id, const char *UNUSED(subdata))
78 {
79  BLI_assert(id != nullptr);
80  /* Store ID-pointer. */
81  id_type = GS(id->name);
82  id_orig = (ID *)id;
83  id_orig_session_uuid = id->session_uuid;
84  eval_flags = 0;
89  is_directly_visible = true;
91  has_base = false;
92  is_user_modified = false;
94 
97 }
98 
99 void IDNode::init_copy_on_write(ID *id_cow_hint)
100 {
101  /* Create pointer as early as possible, so we can use it for function
102  * bindings. Rest of data we'll be copying to the new datablock when
103  * it is actually needed. */
104  if (id_cow_hint != nullptr) {
105  // BLI_assert(deg_copy_on_write_is_needed(id_orig));
107  id_cow = id_cow_hint;
108  }
109  else {
110  id_cow = id_orig;
111  }
112  }
116  "Create shallow copy for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
118  }
119  else {
120  id_cow = id_orig;
121  }
122 }
123 
124 /* Free 'id' node. */
126 {
127  destroy();
128 }
129 
131 {
132  if (id_orig == nullptr) {
133  return;
134  }
135 
136  for (ComponentNode *comp_node : components.values()) {
137  delete comp_node;
138  }
139 
140  /* Free memory used by this CoW ID. */
141  if (!ELEM(id_cow, id_orig, nullptr)) {
143  MEM_freeN(id_cow);
144  id_cow = nullptr;
145  DEG_COW_PRINT("Destroy CoW for %s: id_orig=%p id_cow=%p\n", id_orig->name, id_orig, id_cow);
146  }
147 
148  /* Tag that the node is freed. */
149  id_orig = nullptr;
150 }
151 
152 string IDNode::identifier() const
153 {
154  char orig_ptr[24], cow_ptr[24];
155  BLI_snprintf(orig_ptr, sizeof(orig_ptr), "%p", id_orig);
156  BLI_snprintf(cow_ptr, sizeof(cow_ptr), "%p", id_cow);
157  return string(nodeTypeAsString(type)) + " : " + name + " (orig: " + orig_ptr +
158  ", eval: " + cow_ptr + ", is_directly_visible " +
159  (is_directly_visible ? "true" : "false") + ")";
160 }
161 
163 {
164  ComponentIDKey key(type, name);
165  return components.lookup_default(key, nullptr);
166 }
167 
169 {
170  ComponentNode *comp_node = find_component(type, name);
171  if (!comp_node) {
173  comp_node = (ComponentNode *)factory->create_node(this->id_orig, "", name);
174 
175  /* Register. */
176  ComponentIDKey key(type, name);
177  components.add_new(key, comp_node);
178  comp_node->owner = this;
179  }
180  return comp_node;
181 }
182 
184 {
185  for (ComponentNode *comp_node : components.values()) {
186  /* Relations update does explicit animation update when needed. Here we ignore animation
187  * component to avoid loss of possible unkeyed changes. */
188  if (comp_node->type == NodeType::ANIMATION && source == DEG_UPDATE_SOURCE_RELATIONS) {
189  continue;
190  }
191  comp_node->tag_update(graph, source);
192  }
193 }
194 
196 {
197  /* Finalize build of all components. */
198  for (ComponentNode *comp_node : components.values()) {
199  comp_node->finalize_build(graph);
200  }
202 }
203 
205 {
207  for (ComponentNode *comp_node : components.values()) {
208  if (comp_node->affects_directly_visible) {
209  const int component_type_as_int = static_cast<int>(comp_node->type);
210  BLI_assert(component_type_as_int < 64);
211  result |= (1ULL << component_type_as_int);
212  }
213  }
214  return result;
215 }
216 
217 } // namespace blender::deg
void * BKE_libblock_alloc_notest(short type) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1045
#define BLI_assert(a)
Definition: BLI_assert.h:58
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:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
bool deg_copy_on_write_is_needed(const ID *id_orig)
const char * linkedStateAsString(eDepsNode_LinkedState_Type linked_state)
Definition: deg_node_id.cc:46
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:34
eDepsNode_LinkedState_Type
Definition: deg_node_id.h:40
@ DEG_ID_LINKED_INDIRECTLY
Definition: deg_node_id.h:42
@ DEG_ID_LINKED_VIA_SET
Definition: deg_node_id.h:44
@ DEG_ID_LINKED_DIRECTLY
Definition: deg_node_id.h:46
void deg_free_copy_on_write_datablock(ID *id_cow)
@ DEG_UPDATE_SOURCE_RELATIONS
const char * nodeTypeAsString(NodeType type)
Definition: deg_node.cc:55
unsigned __int64 uint64_t
Definition: stdint.h:93
Definition: DNA_ID.h:273
char name[66]
Definition: DNA_ID.h:283
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:64
ComponentIDKey(NodeType type, const char *name="")
Definition: deg_node_id.cc:60
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:99
DEGCustomDataMeshMasks customdata_masks
Definition: deg_node_id.h:105
DEGCustomDataMeshMasks previous_customdata_masks
Definition: deg_node_id.h:106
ComponentNode * add_component(NodeType type, const char *name="")
Definition: deg_node_id.cc:168
virtual string identifier() const override
Definition: deg_node_id.cc:152
IDComponentsMask visible_components_mask
Definition: deg_node_id.h:126
bool is_collection_fully_expanded
Definition: deg_node_id.h:115
virtual void init(const ID *id, const char *subdata) override
Definition: deg_node_id.cc:77
Map< ComponentIDKey, ComponentNode * > components
Definition: deg_node_id.h:96
IDComponentsMask get_visible_components_mask() const
Definition: deg_node_id.cc:204
void finalize_build(Depsgraph *graph)
Definition: deg_node_id.cc:195
ComponentNode * find_component(NodeType type, const char *name="") const
Definition: deg_node_id.cc:162
eDepsNode_LinkedState_Type linked_state
Definition: deg_node_id.h:108
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override
Definition: deg_node_id.cc:183
uint32_t previous_eval_flags
Definition: deg_node_id.h:102