LibOverride: increase speed of RNA diffing process.
By using own path construction instead of handy printf-like functions, we get a 10% improvement on overall diffing process! This remains way to slow on some complex production characters, but always good to have still.
This commit is contained in:
parent
667ef9917f
commit
44f7852660
Notes:
blender-bot
2023-02-14 05:58:24 +01:00
Referenced by issue #54762, Library Overrides - investigate further performances issues.
|
@ -649,6 +649,7 @@ bool BKE_lib_override_library_status_check_local(Main *bmain, ID *local)
|
|||
&rnaptr_local,
|
||||
&rnaptr_reference,
|
||||
NULL,
|
||||
0,
|
||||
local->override_library,
|
||||
RNA_OVERRIDE_COMPARE_IGNORE_NON_OVERRIDABLE |
|
||||
RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN,
|
||||
|
@ -712,6 +713,7 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local)
|
|||
&rnaptr_local,
|
||||
&rnaptr_reference,
|
||||
NULL,
|
||||
0,
|
||||
local->override_library,
|
||||
RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN,
|
||||
NULL)) {
|
||||
|
@ -771,6 +773,7 @@ bool BKE_lib_override_library_operations_create(Main *bmain,
|
|||
&rnaptr_local,
|
||||
&rnaptr_reference,
|
||||
NULL,
|
||||
0,
|
||||
local->override_library,
|
||||
RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE,
|
||||
&report_flags);
|
||||
|
|
|
@ -1465,6 +1465,7 @@ bool RNA_struct_override_matches(struct Main *bmain,
|
|||
struct PointerRNA *ptr_local,
|
||||
struct PointerRNA *ptr_reference,
|
||||
const char *root_path,
|
||||
const size_t root_path_len,
|
||||
struct IDOverrideLibrary *override,
|
||||
const eRNAOverrideMatch flags,
|
||||
eRNAOverrideMatchResult *r_report_flags);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* \ingroup RNA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
@ -28,7 +30,7 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
// #define DEBUG_OVERRIDE_TIMEIT
|
||||
//#define DEBUG_OVERRIDE_TIMEIT
|
||||
|
||||
#ifdef DEBUG_OVERRIDE_TIMEIT
|
||||
# include "PIL_time_utildefines.h"
|
||||
|
@ -180,6 +182,7 @@ static int rna_property_override_diff(Main *bmain,
|
|||
PropertyRNA *prop_a,
|
||||
PropertyRNA *prop_b,
|
||||
const char *rna_path,
|
||||
const size_t rna_path_len,
|
||||
eRNACompareMode mode,
|
||||
IDOverrideLibrary *override,
|
||||
const int flags,
|
||||
|
@ -191,7 +194,7 @@ bool RNA_property_equals(
|
|||
BLI_assert(ELEM(mode, RNA_EQ_STRICT, RNA_EQ_UNSET_MATCH_ANY, RNA_EQ_UNSET_MATCH_NONE));
|
||||
|
||||
return (rna_property_override_diff(
|
||||
bmain, ptr_a, ptr_b, prop, NULL, NULL, NULL, mode, NULL, 0, NULL) == 0);
|
||||
bmain, ptr_a, ptr_b, prop, NULL, NULL, NULL, 0, mode, NULL, 0, NULL) == 0);
|
||||
}
|
||||
|
||||
bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACompareMode mode)
|
||||
|
@ -249,6 +252,7 @@ static int rna_property_override_diff(Main *bmain,
|
|||
PropertyRNA *prop_a,
|
||||
PropertyRNA *prop_b,
|
||||
const char *rna_path,
|
||||
const size_t rna_path_len,
|
||||
eRNACompareMode mode,
|
||||
IDOverrideLibrary *override,
|
||||
const int flags,
|
||||
|
@ -363,6 +367,7 @@ static int rna_property_override_diff(Main *bmain,
|
|||
mode,
|
||||
override,
|
||||
rna_path,
|
||||
rna_path_len,
|
||||
diff_flags,
|
||||
&override_changed);
|
||||
if (override_changed && r_report_flags) {
|
||||
|
@ -568,6 +573,7 @@ bool RNA_struct_override_matches(Main *bmain,
|
|||
PointerRNA *ptr_local,
|
||||
PointerRNA *ptr_reference,
|
||||
const char *root_path,
|
||||
const size_t root_path_len,
|
||||
IDOverrideLibrary *override,
|
||||
const eRNAOverrideMatch flags,
|
||||
eRNAOverrideMatchResult *r_report_flags)
|
||||
|
@ -649,31 +655,51 @@ bool RNA_struct_override_matches(Main *bmain,
|
|||
#endif
|
||||
|
||||
#define RNA_PATH_BUFFSIZE 8192
|
||||
#define RNA_PATH_PRINTF(_str, ...) \
|
||||
if (BLI_snprintf(rna_path, RNA_PATH_BUFFSIZE, (_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE) { \
|
||||
rna_path = BLI_sprintfN((_str), __VA_ARGS__); \
|
||||
} \
|
||||
(void)0
|
||||
#define RNA_PATH_FREE \
|
||||
if (rna_path != rna_path_buffer) \
|
||||
MEM_freeN(rna_path)
|
||||
|
||||
char rna_path_buffer[RNA_PATH_BUFFSIZE];
|
||||
char *rna_path = rna_path_buffer;
|
||||
size_t rna_path_len = 0;
|
||||
|
||||
/* XXX TODO this will have to be refined to handle collections insertions, and array items */
|
||||
if (root_path) {
|
||||
BLI_assert(strlen(root_path) == root_path_len);
|
||||
|
||||
const char *prop_name = RNA_property_identifier(prop_local);
|
||||
const size_t prop_name_len = strlen(prop_name);
|
||||
|
||||
/* Inlined building, much much more efficient. */
|
||||
if (prop_local->magic == RNA_MAGIC) {
|
||||
RNA_PATH_PRINTF("%s.%s", root_path, RNA_property_identifier(prop_local));
|
||||
rna_path_len = root_path_len + 1 + prop_name_len;
|
||||
if (rna_path_len >= RNA_PATH_BUFFSIZE) {
|
||||
rna_path = MEM_mallocN(rna_path_len + 1, __func__);
|
||||
}
|
||||
|
||||
memcpy(rna_path, root_path, root_path_len);
|
||||
rna_path[root_path_len] = '.';
|
||||
memcpy(rna_path + root_path_len + 1, prop_name, prop_name_len);
|
||||
rna_path[rna_path_len] = '\0';
|
||||
}
|
||||
else {
|
||||
RNA_PATH_PRINTF("%s[\"%s\"]", root_path, RNA_property_identifier(prop_local));
|
||||
rna_path_len = root_path_len + 2 + prop_name_len + 2;
|
||||
if (rna_path_len >= RNA_PATH_BUFFSIZE) {
|
||||
rna_path = MEM_mallocN(rna_path_len + 1, __func__);
|
||||
}
|
||||
|
||||
memcpy(rna_path, root_path, root_path_len);
|
||||
rna_path[root_path_len] = '[';
|
||||
rna_path[root_path_len + 1] = '"';
|
||||
memcpy(rna_path + root_path_len + 2, prop_name, prop_name_len);
|
||||
rna_path[root_path_len + 2 + prop_name_len] = '"';
|
||||
rna_path[root_path_len + 2 + prop_name_len + 1] = ']';
|
||||
rna_path[rna_path_len] = '\0';
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* This is rather slow, but is not much called, so not really worth optimizing. */
|
||||
rna_path = RNA_path_from_ID_to_property(ptr_local, prop_local);
|
||||
if (rna_path != NULL) {
|
||||
rna_path_len = strlen(rna_path);
|
||||
}
|
||||
}
|
||||
if (rna_path == NULL) {
|
||||
continue;
|
||||
|
@ -684,7 +710,10 @@ bool RNA_struct_override_matches(Main *bmain,
|
|||
IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(override, rna_path);
|
||||
if (ignore_overridden && op != NULL) {
|
||||
BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false);
|
||||
RNA_PATH_FREE;
|
||||
|
||||
if (rna_path != rna_path_buffer) {
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -702,6 +731,7 @@ bool RNA_struct_override_matches(Main *bmain,
|
|||
prop_local,
|
||||
prop_reference,
|
||||
rna_path,
|
||||
rna_path_len,
|
||||
RNA_EQ_STRICT,
|
||||
override,
|
||||
flags,
|
||||
|
@ -769,17 +799,18 @@ bool RNA_struct_override_matches(Main *bmain,
|
|||
matching = false;
|
||||
if (!(do_create || do_restore)) {
|
||||
/* Since we have no 'changing' action allowed, we can break here. */
|
||||
MEM_SAFE_FREE(rna_path);
|
||||
if (rna_path != rna_path_buffer) {
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RNA_PATH_FREE;
|
||||
|
||||
if (rna_path != rna_path_buffer) {
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
#undef RNA_PATH_BUFFSIZE
|
||||
#undef RNA_PATH_PRINTF
|
||||
#undef RNA_PATH_FREE
|
||||
}
|
||||
RNA_property_collection_end(&iter);
|
||||
|
||||
|
|
|
@ -498,6 +498,7 @@ int rna_property_override_diff_default(struct Main *bmain,
|
|||
const int mode,
|
||||
struct IDOverrideLibrary *override,
|
||||
const char *rna_path,
|
||||
const size_t rna_path_len,
|
||||
const int flags,
|
||||
bool *r_override_changed);
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@ typedef int (*RNAPropOverrideDiff)(struct Main *bmain,
|
|||
const int mode,
|
||||
struct IDOverrideLibrary *override,
|
||||
const char *rna_path,
|
||||
const size_t rna_path_len,
|
||||
const int flags,
|
||||
bool *r_override_changed);
|
||||
|
||||
|
|
|
@ -1248,6 +1248,7 @@ static int rna_property_override_diff_propptr(Main *bmain,
|
|||
const bool no_prop_name,
|
||||
IDOverrideLibrary *override,
|
||||
const char *rna_path,
|
||||
size_t rna_path_len,
|
||||
const char *rna_itemname_a,
|
||||
const char *rna_itemname_b,
|
||||
const int rna_itemindex_a,
|
||||
|
@ -1324,16 +1325,7 @@ static int rna_property_override_diff_propptr(Main *bmain,
|
|||
|
||||
char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
|
||||
char *extended_rna_path = extended_rna_path_buffer;
|
||||
|
||||
# define RNA_PATH_PRINTF(_str, ...) \
|
||||
if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, (_str), __VA_ARGS__) >= \
|
||||
RNA_PATH_BUFFSIZE - 1) { \
|
||||
extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); \
|
||||
} \
|
||||
(void)0
|
||||
# define RNA_PATH_FREE() \
|
||||
if (extended_rna_path != extended_rna_path_buffer && extended_rna_path != rna_path) \
|
||||
MEM_freeN(extended_rna_path)
|
||||
size_t extended_rna_path_len = 0;
|
||||
|
||||
/* There may be a propname defined in some cases, while no actual name set
|
||||
* (e.g. happens with point cache), in that case too we want to fall back to index.
|
||||
|
@ -1342,31 +1334,82 @@ static int rna_property_override_diff_propptr(Main *bmain,
|
|||
if ((rna_itemname_a != NULL && rna_itemname_a[0] != '\0') &&
|
||||
(rna_itemname_b != NULL && rna_itemname_b[0] != '\0')) {
|
||||
BLI_assert(STREQ(rna_itemname_a, rna_itemname_b));
|
||||
|
||||
char esc_item_name[RNA_PATH_BUFFSIZE];
|
||||
BLI_strescape(esc_item_name, rna_itemname_a, RNA_PATH_BUFFSIZE);
|
||||
RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name);
|
||||
const size_t esc_item_name_len = BLI_strescape(
|
||||
esc_item_name, rna_itemname_a, RNA_PATH_BUFFSIZE);
|
||||
extended_rna_path_len = rna_path_len + 2 + esc_item_name_len + 2;
|
||||
if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) {
|
||||
extended_rna_path = MEM_mallocN(extended_rna_path_len + 1, __func__);
|
||||
}
|
||||
|
||||
memcpy(extended_rna_path, rna_path, rna_path_len);
|
||||
extended_rna_path[rna_path_len] = '[';
|
||||
extended_rna_path[rna_path_len + 1] = '"';
|
||||
memcpy(extended_rna_path + rna_path_len + 2, esc_item_name, esc_item_name_len);
|
||||
extended_rna_path[rna_path_len + 2 + esc_item_name_len] = '"';
|
||||
extended_rna_path[rna_path_len + 2 + esc_item_name_len + 1] = ']';
|
||||
extended_rna_path[extended_rna_path_len] = '\0';
|
||||
}
|
||||
else if (rna_itemindex_a != -1) { /* Based on index... */
|
||||
BLI_assert(rna_itemindex_a == rna_itemindex_b);
|
||||
RNA_PATH_PRINTF("%s[%d]", rna_path, rna_itemindex_a);
|
||||
|
||||
/* low-level specific highly-efficient conversion of positive integer to string. */
|
||||
char item_index_buff[32];
|
||||
size_t item_index_buff_len = 0;
|
||||
if (rna_itemindex_a == 0) {
|
||||
item_index_buff[0] = '0';
|
||||
item_index_buff_len = 1;
|
||||
}
|
||||
else {
|
||||
uint index;
|
||||
for (index = rna_itemindex_a;
|
||||
index > 0 && item_index_buff_len < sizeof(item_index_buff);
|
||||
index /= 10) {
|
||||
item_index_buff[item_index_buff_len++] = '0' + (char)(index % 10);
|
||||
}
|
||||
BLI_assert(index == 0);
|
||||
}
|
||||
|
||||
extended_rna_path_len = rna_path_len + item_index_buff_len + 2;
|
||||
if (extended_rna_path_len >= RNA_PATH_BUFFSIZE) {
|
||||
extended_rna_path = MEM_mallocN(extended_rna_path_len + 1, __func__);
|
||||
}
|
||||
|
||||
memcpy(extended_rna_path, rna_path, rna_path_len);
|
||||
extended_rna_path[rna_path_len] = '[';
|
||||
for (size_t i = 1; i <= item_index_buff_len; i++) {
|
||||
/* The first loop above generated inverted string representation of our index number.
|
||||
*/
|
||||
extended_rna_path[rna_path_len + i] = item_index_buff[item_index_buff_len - i];
|
||||
}
|
||||
extended_rna_path[rna_path_len + 1 + item_index_buff_len] = ']';
|
||||
extended_rna_path[extended_rna_path_len] = '\0';
|
||||
}
|
||||
else {
|
||||
extended_rna_path = (char *)rna_path;
|
||||
extended_rna_path_len = rna_path_len;
|
||||
}
|
||||
}
|
||||
|
||||
eRNAOverrideMatchResult report_flags = 0;
|
||||
const bool match = RNA_struct_override_matches(
|
||||
bmain, propptr_a, propptr_b, extended_rna_path, override, flags, &report_flags);
|
||||
const bool match = RNA_struct_override_matches(bmain,
|
||||
propptr_a,
|
||||
propptr_b,
|
||||
extended_rna_path,
|
||||
extended_rna_path_len,
|
||||
override,
|
||||
flags,
|
||||
&report_flags);
|
||||
if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) {
|
||||
*r_override_changed = true;
|
||||
}
|
||||
|
||||
RNA_PATH_FREE();
|
||||
if (extended_rna_path != extended_rna_path_buffer && extended_rna_path != rna_path) {
|
||||
MEM_freeN(extended_rna_path);
|
||||
}
|
||||
|
||||
# undef RNA_PATH_BUFFSIZE
|
||||
# undef RNA_PATH_PRINTF
|
||||
# undef RNA_PATH_FREE
|
||||
|
||||
return !match;
|
||||
}
|
||||
|
@ -1395,6 +1438,7 @@ int rna_property_override_diff_default(Main *bmain,
|
|||
const int mode,
|
||||
IDOverrideLibrary *override,
|
||||
const char *rna_path,
|
||||
const size_t rna_path_len,
|
||||
const int flags,
|
||||
bool *r_override_changed)
|
||||
{
|
||||
|
@ -1684,6 +1728,7 @@ int rna_property_override_diff_default(Main *bmain,
|
|||
no_prop_name,
|
||||
override,
|
||||
rna_path,
|
||||
rna_path_len,
|
||||
NULL,
|
||||
NULL,
|
||||
-1,
|
||||
|
@ -1844,6 +1889,7 @@ int rna_property_override_diff_default(Main *bmain,
|
|||
no_prop_name,
|
||||
override,
|
||||
rna_path,
|
||||
rna_path_len,
|
||||
propname_a,
|
||||
propname_b,
|
||||
idx_a,
|
||||
|
|
Loading…
Reference in New Issue