Geometry Nodes: split sharing utility for reading and writing
This makes it more obvious that the sharing information is actually completely independent for reading and writing currently.
This commit is contained in:
@@ -58,7 +58,7 @@ struct NodeBakeCache {
|
||||
/** Where to load blobs from disk when loading the baked data lazily. */
|
||||
std::optional<std::string> blobs_dir;
|
||||
/** Used to avoid reading blobs multiple times for different frames. */
|
||||
std::unique_ptr<BlobSharing> blob_sharing;
|
||||
std::unique_ptr<BlobReadSharing> blob_sharing;
|
||||
/** Used to avoid checking if a bake exists many times. */
|
||||
bool failed_finding_bake = false;
|
||||
|
||||
|
||||
@@ -48,10 +48,9 @@ class BlobWriter {
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows for simple data deduplication when writing or reading data by making use of implicit
|
||||
* sharing.
|
||||
* Allows deduplicating data before it's written.
|
||||
*/
|
||||
class BlobSharing {
|
||||
class BlobWriteSharing : NonCopyable, NonMovable {
|
||||
private:
|
||||
struct StoredByRuntimeValue {
|
||||
/**
|
||||
@@ -73,6 +72,25 @@ class BlobSharing {
|
||||
*/
|
||||
Map<const ImplicitSharingInfo *, StoredByRuntimeValue> stored_by_runtime_;
|
||||
|
||||
public:
|
||||
~BlobWriteSharing();
|
||||
|
||||
/**
|
||||
* Check if the data referenced by `sharing_info` has been written before. If yes, return the
|
||||
* identifier for the previously written data. Otherwise, write the data now and store the
|
||||
* identifier for later use.
|
||||
* \return Identifier that indicates from where the data has been written.
|
||||
*/
|
||||
[[nodiscard]] std::shared_ptr<io::serialize::DictionaryValue> write_shared(
|
||||
const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<std::shared_ptr<io::serialize::DictionaryValue>()> write_fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Avoids loading the same data multiple times by caching and sharing previously read buffers.
|
||||
*/
|
||||
class BlobReadSharing : NonCopyable, NonMovable {
|
||||
private:
|
||||
/**
|
||||
* Use a mutex so that #read_shared can be implemented in a thread-safe way.
|
||||
*/
|
||||
@@ -84,17 +102,7 @@ class BlobSharing {
|
||||
mutable Map<std::string, ImplicitSharingInfoAndData> runtime_by_stored_;
|
||||
|
||||
public:
|
||||
~BlobSharing();
|
||||
|
||||
/**
|
||||
* Check if the data referenced by `sharing_info` has been written before. If yes, return the
|
||||
* identifier for the previously written data. Otherwise, write the data now and store the
|
||||
* identifier for later use.
|
||||
* \return Identifier that indicates from where the data has been written.
|
||||
*/
|
||||
[[nodiscard]] std::shared_ptr<io::serialize::DictionaryValue> write_shared(
|
||||
const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<std::shared_ptr<io::serialize::DictionaryValue>()> write_fn);
|
||||
~BlobReadSharing();
|
||||
|
||||
/**
|
||||
* Check if the data identified by `io_data` has been read before or load it now.
|
||||
@@ -139,11 +147,11 @@ class DiskBlobWriter : public BlobWriter {
|
||||
|
||||
void serialize_bake(const BakeState &bake_state,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
std::ostream &r_stream);
|
||||
|
||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing);
|
||||
const BlobReadSharing &blob_sharing);
|
||||
|
||||
} // namespace blender::bke::bake
|
||||
|
||||
@@ -87,11 +87,15 @@ BlobSlice DiskBlobWriter::write(const void *data, const int64_t size)
|
||||
return {blob_name_, {old_offset, size}};
|
||||
}
|
||||
|
||||
BlobSharing::~BlobSharing()
|
||||
BlobWriteSharing::~BlobWriteSharing()
|
||||
{
|
||||
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
|
||||
sharing_info->remove_weak_user_and_delete_if_last();
|
||||
}
|
||||
}
|
||||
|
||||
BlobReadSharing::~BlobReadSharing()
|
||||
{
|
||||
for (const ImplicitSharingInfoAndData &value : runtime_by_stored_.values()) {
|
||||
if (value.sharing_info) {
|
||||
value.sharing_info->remove_user_and_delete_if_last();
|
||||
@@ -99,8 +103,8 @@ BlobSharing::~BlobSharing()
|
||||
}
|
||||
}
|
||||
|
||||
DictionaryValuePtr BlobSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<DictionaryValuePtr()> write_fn)
|
||||
DictionaryValuePtr BlobWriteSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<DictionaryValuePtr()> write_fn)
|
||||
{
|
||||
if (sharing_info == nullptr) {
|
||||
return write_fn();
|
||||
@@ -127,7 +131,7 @@ DictionaryValuePtr BlobSharing::write_shared(const ImplicitSharingInfo *sharing_
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<ImplicitSharingInfoAndData> BlobSharing::read_shared(
|
||||
std::optional<ImplicitSharingInfoAndData> BlobReadSharing::read_shared(
|
||||
const DictionaryValue &io_data,
|
||||
FunctionRef<std::optional<ImplicitSharingInfoAndData>()> read_fn) const
|
||||
{
|
||||
@@ -318,7 +322,7 @@ static std::shared_ptr<DictionaryValue> write_blob_simple_gspan(BlobWriter &blob
|
||||
|
||||
static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
const GSpan data,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
@@ -329,7 +333,7 @@ static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
||||
[[nodiscard]] static const void *read_blob_shared_simple_gspan(
|
||||
const DictionaryValue &io_data,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing,
|
||||
const BlobReadSharing &blob_sharing,
|
||||
const CPPType &cpp_type,
|
||||
const int size,
|
||||
const ImplicitSharingInfo **r_sharing_info)
|
||||
@@ -355,7 +359,7 @@ static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
||||
template<typename T>
|
||||
[[nodiscard]] static bool read_blob_shared_simple_span(const DictionaryValue &io_data,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing,
|
||||
const BlobReadSharing &blob_sharing,
|
||||
const int size,
|
||||
T **r_data,
|
||||
const ImplicitSharingInfo **r_sharing_info)
|
||||
@@ -394,7 +398,7 @@ template<typename T>
|
||||
[[nodiscard]] static bool load_attributes(const io::serialize::ArrayValue &io_attributes,
|
||||
MutableAttributeAccessor &attributes,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
for (const auto &io_attribute_value : io_attributes.elements()) {
|
||||
const auto *io_attribute = io_attribute_value->as_dictionary_value();
|
||||
@@ -453,7 +457,7 @@ template<typename T>
|
||||
|
||||
static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_pointcloud = io_geometry.lookup_dict("pointcloud");
|
||||
if (!io_pointcloud) {
|
||||
@@ -487,7 +491,7 @@ static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
||||
|
||||
static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_curves = io_geometry.lookup_dict("curves");
|
||||
if (!io_curves) {
|
||||
@@ -544,7 +548,7 @@ static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||
|
||||
static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_mesh = io_geometry.lookup_dict("mesh");
|
||||
if (!io_mesh) {
|
||||
@@ -603,11 +607,11 @@ static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||
|
||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing);
|
||||
const BlobReadSharing &blob_sharing);
|
||||
|
||||
static std::unique_ptr<Instances> try_load_instances(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_instances = io_geometry.lookup_dict("instances");
|
||||
if (!io_instances) {
|
||||
@@ -664,7 +668,7 @@ static std::unique_ptr<Instances> try_load_instances(const DictionaryValue &io_g
|
||||
|
||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
GeometrySet geometry;
|
||||
geometry.replace_mesh(try_load_mesh(io_geometry, blob_reader, blob_sharing));
|
||||
@@ -699,7 +703,7 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_materials(
|
||||
static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||
const AttributeAccessor &attributes,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
const Set<std::string> &attributes_to_ignore)
|
||||
{
|
||||
auto io_attributes = std::make_shared<io::serialize::ArrayValue>();
|
||||
@@ -734,7 +738,7 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||
|
||||
static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet &geometry,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing)
|
||||
BlobWriteSharing &blob_sharing)
|
||||
{
|
||||
auto io_geometry = std::make_shared<DictionaryValue>();
|
||||
if (geometry.has_mesh()) {
|
||||
@@ -1007,7 +1011,7 @@ template<typename T>
|
||||
|
||||
static void serialize_bake_item(const BakeItem &item,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
DictionaryValue &r_io_item)
|
||||
{
|
||||
if (!item.name.empty()) {
|
||||
@@ -1046,7 +1050,7 @@ static void serialize_bake_item(const BakeItem &item,
|
||||
|
||||
static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io_item,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
|
||||
const std::optional<StringRefNull> state_item_type = io_item.lookup_str("type");
|
||||
@@ -1115,7 +1119,7 @@ static constexpr int bake_file_version = 3;
|
||||
|
||||
void serialize_bake(const BakeState &bake_state,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
BlobWriteSharing &blob_sharing,
|
||||
std::ostream &r_stream)
|
||||
{
|
||||
io::serialize::DictionaryValue io_root;
|
||||
@@ -1132,7 +1136,7 @@ void serialize_bake(const BakeState &bake_state,
|
||||
|
||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
const BlobReadSharing &blob_sharing)
|
||||
{
|
||||
JsonFormatter formatter;
|
||||
std::unique_ptr<io::serialize::Value> io_root_value;
|
||||
|
||||
@@ -228,7 +228,7 @@ struct NodeBakeRequest {
|
||||
bake::BakePath path;
|
||||
int frame_start;
|
||||
int frame_end;
|
||||
std::unique_ptr<bake::BlobSharing> blob_sharing;
|
||||
std::unique_ptr<bake::BlobWriteSharing> blob_sharing;
|
||||
};
|
||||
|
||||
struct BakeGeometryNodesJob {
|
||||
@@ -481,7 +481,7 @@ static Vector<NodeBakeRequest> collect_simulations_to_bake(Main &bmain,
|
||||
request.nmd = nmd;
|
||||
request.bake_id = id;
|
||||
request.node_type = node->type;
|
||||
request.blob_sharing = std::make_unique<bake::BlobSharing>();
|
||||
request.blob_sharing = std::make_unique<bake::BlobWriteSharing>();
|
||||
std::optional<bake::BakePath> path = bake::get_node_bake_path(bmain, *object, *nmd, id);
|
||||
if (!path) {
|
||||
continue;
|
||||
@@ -832,7 +832,7 @@ static Vector<NodeBakeRequest> bake_single_node_gather_bake_request(bContext *C,
|
||||
request.nmd = &nmd;
|
||||
request.bake_id = bake_id;
|
||||
request.node_type = node->type;
|
||||
request.blob_sharing = std::make_unique<bake::BlobSharing>();
|
||||
request.blob_sharing = std::make_unique<bake::BlobWriteSharing>();
|
||||
|
||||
const NodesModifierBake *bake = nmd.find_bake(bake_id);
|
||||
if (!bake) {
|
||||
|
||||
@@ -979,7 +979,7 @@ static bool try_find_baked_data(bake::NodeBakeCache &bake,
|
||||
bake.frames.append(std::move(frame_cache));
|
||||
}
|
||||
bake.blobs_dir = bake_path->blobs_dir;
|
||||
bake.blob_sharing = std::make_unique<bake::BlobSharing>();
|
||||
bake.blob_sharing = std::make_unique<bake::BlobReadSharing>();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user