LibOverride: Make diffing several times faster.
Diffing on undo steps is a critical performance point of override system, although not required for override itself, it gives user immediate feedback ove what is overridden. Profiling showed that rna path text search over overrides operations was by far the most costly thing here, so now using a runtime temp ghash mapping for this search instead. Seems to give at least 5 times speedup on big production rig.
This commit is contained in:
parent
cfb7f508ce
commit
2a38b857f7
Notes:
blender-bot
2023-02-14 06:25:25 +01:00
Referenced by issue #54762, Library Overrides - investigate further performances issues.
|
@ -36,6 +36,7 @@
|
|||
#include "BKE_main.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
|
@ -148,6 +149,10 @@ void BKE_override_library_clear(IDOverrideLibrary *override, const bool do_id_us
|
|||
{
|
||||
BLI_assert(override != NULL);
|
||||
|
||||
if (override->runtime != NULL) {
|
||||
BLI_ghash_clear(override->runtime, NULL, NULL);
|
||||
}
|
||||
|
||||
for (IDOverrideLibraryProperty *op = override->properties.first; op; op = op->next) {
|
||||
bke_override_property_clear(op);
|
||||
}
|
||||
|
@ -164,6 +169,11 @@ void BKE_override_library_free(struct IDOverrideLibrary **override, const bool d
|
|||
{
|
||||
BLI_assert(*override != NULL);
|
||||
|
||||
if ((*override)->runtime != NULL) {
|
||||
BLI_ghash_free((*override)->runtime, NULL, NULL);
|
||||
(*override)->runtime = NULL;
|
||||
}
|
||||
|
||||
BKE_override_library_clear(*override, do_id_user);
|
||||
MEM_freeN(*override);
|
||||
*override = NULL;
|
||||
|
@ -285,15 +295,28 @@ bool BKE_override_library_create_from_tag(Main *bmain)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* We only build override GHash on request. */
|
||||
BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
|
||||
IDOverrideLibrary *override)
|
||||
{
|
||||
if (override->runtime == NULL) {
|
||||
override->runtime = BLI_ghash_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
|
||||
for (IDOverrideLibraryProperty *op = override->properties.first; op != NULL; op = op->next) {
|
||||
BLI_ghash_insert(override->runtime, op->rna_path, op);
|
||||
}
|
||||
}
|
||||
|
||||
return override->runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find override property from given RNA path, if it exists.
|
||||
*/
|
||||
IDOverrideLibraryProperty *BKE_override_library_property_find(IDOverrideLibrary *override,
|
||||
const char *rna_path)
|
||||
{
|
||||
/* XXX TODO we'll most likely want a runtime ghash to store that mapping at some point. */
|
||||
return BLI_findstring_ptr(
|
||||
&override->properties, rna_path, offsetof(IDOverrideLibraryProperty, rna_path));
|
||||
IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(override);
|
||||
return BLI_ghash_lookup(override_runtime, rna_path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,7 +326,6 @@ IDOverrideLibraryProperty *BKE_override_library_property_get(IDOverrideLibrary *
|
|||
const char *rna_path,
|
||||
bool *r_created)
|
||||
{
|
||||
/* XXX TODO we'll most likely want a runtime ghash to store that mapping at some point. */
|
||||
IDOverrideLibraryProperty *op = BKE_override_library_property_find(override, rna_path);
|
||||
|
||||
if (op == NULL) {
|
||||
|
@ -311,6 +333,10 @@ IDOverrideLibraryProperty *BKE_override_library_property_get(IDOverrideLibrary *
|
|||
op->rna_path = BLI_strdup(rna_path);
|
||||
BLI_addtail(&override->properties, op);
|
||||
|
||||
IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(
|
||||
override);
|
||||
BLI_ghash_insert(override_runtime, op->rna_path, op);
|
||||
|
||||
if (r_created) {
|
||||
*r_created = true;
|
||||
}
|
||||
|
@ -355,6 +381,9 @@ void BKE_override_library_property_delete(IDOverrideLibrary *override,
|
|||
IDOverrideLibraryProperty *override_property)
|
||||
{
|
||||
bke_override_property_clear(override_property);
|
||||
if (override->runtime != NULL) {
|
||||
BLI_ghash_remove(override->runtime, override_property->rna_path, NULL, NULL);
|
||||
}
|
||||
BLI_freelinkN(&override->properties, override_property);
|
||||
}
|
||||
|
||||
|
|
|
@ -2668,6 +2668,7 @@ static void direct_link_id(FileData *fd, ID *id)
|
|||
if (id->override_library) {
|
||||
id->override_library = newdataadr(fd, id->override_library);
|
||||
link_list_ex(fd, &id->override_library->properties, direct_link_id_override_property_cb);
|
||||
id->override_library->runtime = NULL;
|
||||
}
|
||||
|
||||
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||
|
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct FileData;
|
||||
struct GHash;
|
||||
struct GPUTexture;
|
||||
struct ID;
|
||||
struct Library;
|
||||
|
@ -206,6 +207,9 @@ typedef struct IDOverrideLibraryProperty {
|
|||
ListBase operations;
|
||||
} IDOverrideLibraryProperty;
|
||||
|
||||
/* We do not need a full struct for that currently, just a GHash. */
|
||||
typedef struct GHash IDOverrideLibraryRuntime;
|
||||
|
||||
/* Main container for all overriding data info of a data-block. */
|
||||
typedef struct IDOverrideLibrary {
|
||||
/** Reference linked ID which this one overrides. */
|
||||
|
@ -220,6 +224,8 @@ typedef struct IDOverrideLibrary {
|
|||
/* Temp ID storing extra override data (used for differential operations only currently).
|
||||
* Always NULL outside of read/write context. */
|
||||
struct ID *storage;
|
||||
|
||||
IDOverrideLibraryRuntime *runtime;
|
||||
} IDOverrideLibrary;
|
||||
|
||||
enum eOverrideLibrary_Flag {
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#define DEBUG_OVERRIDE_TIMEIT
|
||||
|
||||
#ifdef DEBUG_OVERRIDE_TIMEIT
|
||||
# include "PIL_time_utildefines.h"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue