Simulation Nodes: bake simulation states to disk #106937

Merged
Jacques Lucke merged 116 commits from JacquesLucke/blender:sim-bake into geometry-nodes-simulation 2023-04-22 14:48:56 +02:00
3 changed files with 77 additions and 10 deletions
Showing only changes of commit fcb888a00c - Show all commits

View File

@ -34,18 +34,34 @@ class BDataWriter {
class BDataSharing {
private:
struct StoredValue {
struct StoredByRuntimeValue {
int64_t sharing_info_version;
DictionaryValuePtr io_data;
};
Map<const ImplicitSharingInfo *, StoredValue> map_;
struct RuntimeByStoredValue {
const ImplicitSharingInfo *sharing_info;
int64_t sharing_info_version;
const void *data;
};
/** The #ImplicitSharingInfo pointer is a weak user. */
Map<const ImplicitSharingInfo *, StoredByRuntimeValue> stored_by_runtime_;
Map<std::string, RuntimeByStoredValue> runtime_by_stored_;
public:
~BDataSharing();
DictionaryValuePtr write_shared(const ImplicitSharingInfo *sharing_info,
FunctionRef<DictionaryValuePtr()> write_fn);
struct SharingInfoWithData {
const ImplicitSharingInfo *sharing_info;
const void *data;
};
SharingInfoWithData read_shared(const DictionaryValue &io_data,
FunctionRef<SharingInfoWithData()> read_fn);
};
class DiskBDataReader : public BDataReader {

View File

@ -781,9 +781,14 @@ BDataSlice DiskBDataWriter::write(const void *data, const int64_t size)
BDataSharing::~BDataSharing()
{
for (const ImplicitSharingInfo *sharing_info : map_.keys()) {
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
sharing_info->remove_weak_user_and_delete_if_last();
}
for (const RuntimeByStoredValue &value : runtime_by_stored_.values()) {
if (value.sharing_info) {
value.sharing_info->remove_weak_user_and_delete_if_last();
}
}
}
DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing_info,
@ -792,18 +797,18 @@ DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing
if (sharing_info == nullptr) {
return write_fn();
}
return map_.add_or_modify(
return stored_by_runtime_.add_or_modify(
sharing_info,
/* Create new value. */
[&](StoredValue *value) {
new (value) StoredValue();
[&](StoredByRuntimeValue *value) {
new (value) StoredByRuntimeValue();
value->io_data = write_fn();
value->sharing_info_version = sharing_info->version();
sharing_info->add_weak_user();
return value->io_data;
},
/* Potentially modify existing value. */
[&](StoredValue *value) {
[&](StoredByRuntimeValue *value) {
const int64_t new_version = sharing_info->version();
BLI_assert(value->sharing_info_version <= new_version);
if (value->sharing_info_version < new_version) {
@ -814,4 +819,50 @@ DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing
});
}
BDataSharing::SharingInfoWithData BDataSharing::read_shared(
const DictionaryValue &io_data, FunctionRef<SharingInfoWithData()> read_fn)
{
io::serialize::JsonFormatter formatter;
std::stringstream ss;
formatter.serialize(ss, io_data);
const std::string key = ss.str();
return runtime_by_stored_.add_or_modify_as(
key,
[&](RuntimeByStoredValue *value) {
new (value) RuntimeByStoredValue();
const SharingInfoWithData data = read_fn();
value->sharing_info = data.sharing_info;
if (value->sharing_info != nullptr) {
value->sharing_info->add_weak_user();
value->sharing_info_version = value->sharing_info->version();
}
value->data = data.data;
return data;
},
[&](RuntimeByStoredValue *value) {
/* Try to use existing data. */
if (value->sharing_info) {
if (value->sharing_info->add_user_if_not_expired()) {
if (value->sharing_info_version == value->sharing_info->version()) {
return SharingInfoWithData{value->sharing_info, value->data};
}
value->sharing_info->remove_user_and_delete_if_last();
}
value->sharing_info->remove_weak_user_and_delete_if_last();
value->sharing_info = nullptr;
}
/* Can't use existing data, load again. */
const SharingInfoWithData data = read_fn();
value->sharing_info = data.sharing_info;
if (value->sharing_info) {
value->sharing_info->add_weak_user();
value->sharing_info_version = value->sharing_info->version();
}
value->data = data.data;
return data;
});
}
} // namespace blender::bke::sim

View File

@ -53,7 +53,7 @@ class ImplicitSharingInfo : NonCopyable, NonMovable {
* incremented whenever the referenced data is about to be changed. This allows weak users to
* detect if the data has changed since the weak user was created.
*/
mutable int64_t version_ = 0;
mutable std::atomic<int64_t> version_ = 0;
public:
virtual ~ImplicitSharingInfo()
@ -126,7 +126,7 @@ class ImplicitSharingInfo : NonCopyable, NonMovable {
BLI_assert(this->is_mutable());
/* Does not need an atomic increment, because if the data is mutable, there is only a single
* owner that may call this at a time. */
version_++;
version_.fetch_add(1, std::memory_order_acq_rel);
}
/**
@ -136,7 +136,7 @@ class ImplicitSharingInfo : NonCopyable, NonMovable {
*/
int64_t version() const
{
return version_;
return version_.load(std::memory_order_acquire);
}
/**