diff --git a/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh b/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh index 1906690054e..c1f0982a9d8 100644 --- a/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh +++ b/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh @@ -58,7 +58,7 @@ struct NodeBakeCache { /** Where to load blobs from disk when loading the baked data lazily. */ std::optional blobs_dir; /** Used to avoid reading blobs multiple times for different frames. */ - std::unique_ptr blob_sharing; + std::unique_ptr blob_sharing; /** Used to avoid checking if a bake exists many times. */ bool failed_finding_bake = false; diff --git a/source/blender/blenkernel/BKE_bake_items_serialize.hh b/source/blender/blenkernel/BKE_bake_items_serialize.hh index b008a6be601..2740a98d972 100644 --- a/source/blender/blenkernel/BKE_bake_items_serialize.hh +++ b/source/blender/blenkernel/BKE_bake_items_serialize.hh @@ -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 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 write_shared( + const ImplicitSharingInfo *sharing_info, + FunctionRef()> 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 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 write_shared( - const ImplicitSharingInfo *sharing_info, - FunctionRef()> 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 deserialize_bake(std::istream &stream, const BlobReader &blob_reader, - const BlobSharing &blob_sharing); + const BlobReadSharing &blob_sharing); } // namespace blender::bke::bake diff --git a/source/blender/blenkernel/intern/bake_items_serialize.cc b/source/blender/blenkernel/intern/bake_items_serialize.cc index 3c9c8c28b86..b2d3ad96d89 100644 --- a/source/blender/blenkernel/intern/bake_items_serialize.cc +++ b/source/blender/blenkernel/intern/bake_items_serialize.cc @@ -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 write_fn) +DictionaryValuePtr BlobWriteSharing::write_shared(const ImplicitSharingInfo *sharing_info, + FunctionRef write_fn) { if (sharing_info == nullptr) { return write_fn(); @@ -127,7 +131,7 @@ DictionaryValuePtr BlobSharing::write_shared(const ImplicitSharingInfo *sharing_ }); } -std::optional BlobSharing::read_shared( +std::optional BlobReadSharing::read_shared( const DictionaryValue &io_data, FunctionRef()> read_fn) const { @@ -318,7 +322,7 @@ static std::shared_ptr write_blob_simple_gspan(BlobWriter &blob static std::shared_ptr 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 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 write_blob_shared_simple_gspan( template [[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 [[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 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 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 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 serialize_materials( static std::shared_ptr serialize_attributes( const AttributeAccessor &attributes, BlobWriter &blob_writer, - BlobSharing &blob_sharing, + BlobWriteSharing &blob_sharing, const Set &attributes_to_ignore) { auto io_attributes = std::make_shared(); @@ -734,7 +738,7 @@ static std::shared_ptr serialize_attributes( static std::shared_ptr serialize_geometry_set(const GeometrySet &geometry, BlobWriter &blob_writer, - BlobSharing &blob_sharing) + BlobWriteSharing &blob_sharing) { auto io_geometry = std::make_shared(); if (geometry.has_mesh()) { @@ -1007,7 +1011,7 @@ template 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 deserialize_bake_item(const DictionaryValue &io_item, const BlobReader &blob_reader, - const BlobSharing &blob_sharing) + const BlobReadSharing &blob_sharing) { const std::optional 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 deserialize_bake(std::istream &stream, const BlobReader &blob_reader, - const BlobSharing &blob_sharing) + const BlobReadSharing &blob_sharing) { JsonFormatter formatter; std::unique_ptr io_root_value; diff --git a/source/blender/editors/object/object_bake_simulation.cc b/source/blender/editors/object/object_bake_simulation.cc index 49de4a4dd32..764163467c1 100644 --- a/source/blender/editors/object/object_bake_simulation.cc +++ b/source/blender/editors/object/object_bake_simulation.cc @@ -228,7 +228,7 @@ struct NodeBakeRequest { bake::BakePath path; int frame_start; int frame_end; - std::unique_ptr blob_sharing; + std::unique_ptr blob_sharing; }; struct BakeGeometryNodesJob { @@ -481,7 +481,7 @@ static Vector collect_simulations_to_bake(Main &bmain, request.nmd = nmd; request.bake_id = id; request.node_type = node->type; - request.blob_sharing = std::make_unique(); + request.blob_sharing = std::make_unique(); std::optional path = bake::get_node_bake_path(bmain, *object, *nmd, id); if (!path) { continue; @@ -832,7 +832,7 @@ static Vector 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(); + request.blob_sharing = std::make_unique(); const NodesModifierBake *bake = nmd.find_bake(bake_id); if (!bake) { diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 9841551c753..f6713b56f6a 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -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.blob_sharing = std::make_unique(); return true; }