Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-02-11 16:42:36 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-02-11 16:42:36 +0300
commit18ac37a39b7d74e0fb76cf2b1a09c470c32a68bf (patch)
treeac9a043bce6284dbbb3062ca7e78b116519d3c0c /source
parentdabf96f732d1ce5f44f53230317ff0d0b8a380df (diff)
parent196dfc01a3e99c3bef0e44acf599bca50ae0300e (diff)
Merge branch 'blender-v2.92-release'
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_customdata.h1
-rw-r--r--source/blender/blenkernel/intern/customdata.c12
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c22
3 files changed, 35 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 51650d161ea..57fdafaf8d9 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -421,6 +421,7 @@ int CustomData_sizeof(int type);
/* get the name of a layer type */
const char *CustomData_layertype_name(int type);
bool CustomData_layertype_is_singleton(int type);
+bool CustomData_layertype_is_dynamic(int type);
int CustomData_layertype_layers_max(const int type);
/* make sure the name of layer at index is unique */
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 37e9c810123..782b4fc200e 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -4273,6 +4273,18 @@ bool CustomData_layertype_is_singleton(int type)
}
/**
+ * Has dynamically allocated members.
+ * This is useful to know if operations such as #memcmp are
+ * valid when comparing data from two layers.
+ */
+bool CustomData_layertype_is_dynamic(int type)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ return (typeInfo->free != NULL);
+}
+
+/**
* \return Maximum number of layers of given \a type, -1 means 'no limit'.
*/
int CustomData_layertype_layers_max(const int type)
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index d7f7cfa2888..dd51d63961c 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -153,6 +153,23 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
for (int layer_start = 0, layer_end; layer_start < cdata->totlayer; layer_start = layer_end) {
const CustomDataType type = cdata->layers[layer_start].type;
+ /* Perform a full copy on dynamic layers.
+ *
+ * Unfortunately we can't compare dynamic layer types as they contain allocated pointers,
+ * which burns CPU cycles looking for duplicate data that doesn't exist.
+ * The array data isn't comparable once copied from the mesh,
+ * this bottlenecks on high poly meshes, see T84114.
+ *
+ * Notes:
+ *
+ * - Ideally the data would be expanded into a format that could be de-duplicated effectively,
+ * this would require a flat representation of each dynamic custom-data layer.
+ *
+ * - The data in the layer could be kept as-is to save on the extra copy,
+ * it would complicate logic in this function.
+ */
+ const bool layer_type_is_dynamic = CustomData_layertype_is_dynamic(type);
+
layer_end = layer_start + 1;
while ((layer_end < cdata->totlayer) && (type == cdata->layers[layer_end].type)) {
layer_end++;
@@ -209,6 +226,11 @@ static void um_arraystore_cd_compact(struct CustomData *cdata,
i < bcd_reference_current->states_len) ?
bcd_reference_current->states[i] :
NULL;
+ /* See comment on `layer_type_is_dynamic` above. */
+ if (layer_type_is_dynamic) {
+ state_reference = NULL;
+ }
+
bcd->states[i] = BLI_array_store_state_add(
bs, layer->data, (size_t)data_len * stride, state_reference);
}