[Bf-blender-cvs] [c42ceef0401] temp-geometry-nodes-fields--anonymous-attributes: initial anonymous attributes implementation

Jacques Lucke noreply at git.blender.org
Mon Aug 23 18:40:37 CEST 2021


Commit: c42ceef04010a91c9b31e5c026d49331647687b5
Author: Jacques Lucke
Date:   Mon Aug 23 18:40:29 2021 +0200
Branches: temp-geometry-nodes-fields--anonymous-attributes
https://developer.blender.org/rBc42ceef04010a91c9b31e5c026d49331647687b5

initial anonymous attributes implementation

===================================================================

A	source/blender/blenkernel/BKE_anonymous_attribute.h
A	source/blender/blenkernel/BKE_anonymous_attribute.hh
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/anonymous_attribute.cc
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/makesdna/DNA_customdata_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.h b/source/blender/blenkernel/BKE_anonymous_attribute.h
new file mode 100644
index 00000000000..cc9604dd99d
--- /dev/null
+++ b/source/blender/blenkernel/BKE_anonymous_attribute.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct AnonymousAttributeID AnonymousAttributeID;
+
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_weak(const char *debug_name);
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_strong(const char *debug_name);
+bool BKE_anonymous_attribute_id_has_strong_references(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_increment_weak(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_increment_strong(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_decrement_weak(const AnonymousAttributeID *anonymous_id);
+void BKE_anonymous_attribute_id_decrement_strong(const AnonymousAttributeID *anonymous_id);
+const char *BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.hh b/source/blender/blenkernel/BKE_anonymous_attribute.hh
new file mode 100644
index 00000000000..e0f2940eaf2
--- /dev/null
+++ b/source/blender/blenkernel/BKE_anonymous_attribute.hh
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <string>
+
+#include "BLI_string_ref.hh"
+
+#include "BKE_anonymous_attribute.h"
+
+namespace blender::bke {
+
+template<bool IsStrongReference> class OwnedAnonymousAttributeID {
+ private:
+  AnonymousAttributeID *data_ = nullptr;
+
+ public:
+  OwnedAnonymousAttributeID() = default;
+
+  explicit OwnedAnonymousAttributeID(StringRefNull debug_name)
+  {
+    if constexpr (IsStrongReference) {
+      data_ = BKE_anonymous_attribute_id_new_strong(debug_name.c_str());
+    }
+    else {
+      data_ = BKE_anonymous_attribute_id_new_weak(debug_name.c_str());
+    }
+  }
+
+  /* This transfers ownership, so no incref is necessary. */
+  explicit OwnedAnonymousAttributeID(AnonymousAttributeID *anonymous_id) : data_(anonymous_id)
+  {
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID(const OwnedAnonymousAttributeID<OtherIsStrong> &other)
+  {
+    data_ = other.data_;
+    this->incref();
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID(OwnedAnonymousAttributeID<OtherIsStrong> &&other)
+  {
+    data_ = other.data_;
+    this->incref();
+    other.decref();
+    other.data_ = nullptr;
+  }
+
+  ~OwnedAnonymousAttributeID()
+  {
+    this->decref();
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID &operator=(const OwnedAnonymousAttributeID<OtherIsStrong> &other)
+  {
+    if (this == &other) {
+      return *this;
+    }
+    this->~OwnedAnonymousAttributeID();
+    new (this) OwnedAnonymousAttributeID(other);
+    return *this;
+  }
+
+  template<bool OtherIsStrong>
+  OwnedAnonymousAttributeID &operator=(OwnedAnonymousAttributeID<OtherIsStrong> &&other)
+  {
+    if (this == &other) {
+      return *this;
+    }
+    this->~OwnedAnonymousAttributeID();
+    new (this) OwnedAnonymousAttributeID(std::move(other));
+    return *this;
+  }
+
+  operator bool() const
+  {
+    return data_ != nullptr;
+  }
+
+  StringRefNull debug_name() const
+  {
+    BLI_assert(data_ != nullptr);
+    return BKE_anonymous_attribute_id_debug_name(data_);
+  }
+
+  bool has_strong_references() const
+  {
+    BLI_assert(data_ != nullptr);
+    return BKE_anonymous_attribute_id_has_strong_references(data_);
+  }
+
+  AnonymousAttributeID *extract()
+  {
+    AnonymousAttributeID *extracted_data = data_;
+    /* Don't decref because the caller becomes the new owner. */
+    data_ = nullptr;
+    return extracted_data;
+  }
+
+ private:
+  void incref()
+  {
+    if (data_ == nullptr) {
+      return;
+    }
+    if constexpr (IsStrongReference) {
+      BKE_anonymous_attribute_id_increment_strong(data_);
+    }
+    else {
+      BKE_anonymous_attribute_id_increment_weak(data_);
+    }
+  }
+
+  void decref()
+  {
+    if (data_ == nullptr) {
+      return;
+    }
+    if constexpr (IsStrongReference) {
+      BKE_anonymous_attribute_id_decrement_strong(data_);
+    }
+    else {
+      BKE_anonymous_attribute_id_decrement_weak(data_);
+    }
+  }
+};
+
+using StrongAnonymousAttributeID = OwnedAnonymousAttributeID<true>;
+using WeakAnonymousAttributeID = OwnedAnonymousAttributeID<false>;
+
+}  // namespace blender::bke
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index adaef22d5bc..00551acd4bc 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -76,6 +76,7 @@ set(SRC
   intern/anim_path.c
   intern/anim_sys.c
   intern/anim_visualization.c
+  intern/anonymous_attribute.cc
   intern/appdir.c
   intern/armature.c
   intern/armature_selection.cc
@@ -295,6 +296,8 @@ set(SRC
   BKE_anim_path.h
   BKE_anim_visualization.h
   BKE_animsys.h
+  BKE_anonymous_attribute.h
+  BKE_anonymous_attribute.hh
   BKE_appdir.h
   BKE_armature.h
   BKE_armature.hh
diff --git a/source/blender/blenkernel/intern/anonymous_attribute.cc b/source/blender/blenkernel/intern/anonymous_attribute.cc
new file mode 100644
index 00000000000..8d9cddcbcb4
--- /dev/null
+++ b/source/blender/blenkernel/intern/anonymous_attribute.cc
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#include "BKE_anonymous_attribute.hh"
+
+using namespace blender::bke;
+
+struct AnonymousAttributeID {
+  mutable std::atomic<int> refcount_weak;
+  mutable std::atomic<int> refcount_strong;
+  std::string debug_name;
+};
+
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_weak(const char *debug_name)
+{
+  AnonymousAttributeID *anonymous_id = new AnonymousAttributeID();
+  anonymous_id->debug_name = debug_name;
+  anonymous_id->refcount_weak.store(1);
+  return anonymous_id;
+}
+
+AnonymousAttributeID *BKE_anonymous_attribute_id_new_strong(const char *debug_name)
+{
+  AnonymousAttributeID *anonymous_id = new AnonymousAttributeID();
+  anonymous_id->debug_name = debug_name;
+  anonymous_id->refcount_weak.store(1);
+  anonymous_id->refcount_strong.store(1);
+  return anonymous_id;
+}
+
+bool BKE_anonymous_attribute_id_has_strong_references(const AnonymousAttributeID *anonymous_id)
+{
+  return anonymous_id->refcount_strong.load() >= 1;
+}
+
+void BKE_anonymous_attribute_id_increment_weak(const AnonymousAttributeID *anonymous_id)
+{
+  anonymous_id->refcount_weak.fetch_add(1);
+}
+
+void BKE_anonymous_attribute_id_increment_strong(const AnonymousAttributeID *anonymous_id)
+{
+  anonymous_id->refcount_weak.fetch_add(1);
+  anonymous_id->refcount_strong.fetch_add(1);
+}
+
+void BKE_anonymous_attribute_id_decrement_weak(const AnonymousAttributeID *anonymous_id)
+{
+  const int new_refcount = anonymous_id->refcount_weak.fetch_sub(1) - 1;
+  if (new_refcount == 0) {
+    delete anonymous_id;
+  }
+}
+
+void BKE_anonymous_attribute_id_decrement_strong(const AnonymousAttributeID *anonymous_id)
+{
+  anonymous_id->refcount_strong.fetch_sub(1);
+  BKE_anonymous_attribute_id_decrement_weak(anonymous_id);
+}
+
+const char *BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id)
+{
+  return anonymous_id->debug_name.c_str();
+}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 1a3200a9b6c..30fabe09602 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -46,6 +46,7 @@
 
 #include "BLT_translation.h"
 
+#include "BKE_anonymous_attribute.h"
 #include "BKE_customdata.h"
 #include "BKE_customdata_file.h"
 #include "BKE_deform.h"
@@ -2127,6 +2128,10 @@ bool CustomData_merge(const struct CustomData *source,
     if (flag & CD_FLAG_NOCOPY) {
       continue;
     }
+    if (layer->anonymous_id &&
+        !BKE_anonymous_attribute_id_has_strong_references(layer->anonymous_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list