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:
Jacques Lucke
2024-02-02 17:01:04 +01:00
parent deb4273565
commit da540a73de
5 changed files with 53 additions and 41 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;
}