BLI: reduce binary size for non-performance sensitive virtual arrays
This adds a `VArray::from_std_func` next to the existing `VArray::from_func`. It does almost the same but inserts some type erasure by using `std::function` which avoids the need to instantiate the full virtual array. This has is a bit slower at run-time, but in practice there are some cases where it doesn't matter. Currently, this patch reduces binary size by ~35kb. Not too much, but still good or such a simple change. Pull Request: https://projects.blender.org/blender/blender/pulls/146011
This commit is contained in:
@@ -913,6 +913,15 @@ template<typename T> class VArray : public VArrayCommon<T> {
|
||||
return VArray::from<VArrayImpl_For_Func<T, decltype(get_func)>>(size, std::move(get_func));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as #from_func, but uses a std::function instead of a template. This is slower, but
|
||||
* requires less code generation. Therefore this should be used in non-performance critical code.
|
||||
*/
|
||||
static VArray from_std_func(const int64_t size, std::function<T(int64_t index)> get_func)
|
||||
{
|
||||
return VArray::from_func(size, get_func);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new virtual array for an existing span with a mapping function. This does not take
|
||||
* ownership of the span.
|
||||
|
||||
@@ -1198,27 +1198,27 @@ static VArray<bool> get_fill_boundary_layers(const GreasePencil &grease_pencil,
|
||||
|
||||
switch (fill_layer_mode) {
|
||||
case GP_FILL_GPLMODE_ACTIVE:
|
||||
return VArray<bool>::from_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return index != active_layer_index;
|
||||
});
|
||||
case GP_FILL_GPLMODE_ABOVE:
|
||||
return VArray<bool>::from_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return index != active_layer_index + 1;
|
||||
});
|
||||
case GP_FILL_GPLMODE_BELOW:
|
||||
return VArray<bool>::from_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return index != active_layer_index - 1;
|
||||
});
|
||||
case GP_FILL_GPLMODE_ALL_ABOVE:
|
||||
return VArray<bool>::from_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return index <= active_layer_index;
|
||||
});
|
||||
case GP_FILL_GPLMODE_ALL_BELOW:
|
||||
return VArray<bool>::from_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [active_layer_index](const int index) {
|
||||
return index >= active_layer_index;
|
||||
});
|
||||
case GP_FILL_GPLMODE_VISIBLE:
|
||||
return VArray<bool>::from_func(all_layers.size(), [grease_pencil](const int index) {
|
||||
return VArray<bool>::from_std_func(all_layers.size(), [grease_pencil](const int index) {
|
||||
return !grease_pencil.layers()[index]->is_visible();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ static std::unique_ptr<ColumnValues> build_mesh_debug_columns(const Mesh &mesh,
|
||||
if (name == "Corner Size") {
|
||||
const OffsetIndices faces = mesh.faces();
|
||||
return std::make_unique<ColumnValues>(
|
||||
name, VArray<int>::from_func(faces.size(), [faces](int64_t index) {
|
||||
name, VArray<int>::from_std_func(faces.size(), [faces](int64_t index) {
|
||||
return faces[index].size();
|
||||
}));
|
||||
}
|
||||
@@ -244,7 +244,7 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
|
||||
Span<bke::InstanceReference> references = instances->references();
|
||||
return std::make_unique<ColumnValues>(
|
||||
column_id.name,
|
||||
VArray<bke::InstanceReference>::from_func(
|
||||
VArray<bke::InstanceReference>::from_std_func(
|
||||
domain_num, [reference_handles, references](int64_t index) {
|
||||
return references[reference_handles[index]];
|
||||
}));
|
||||
@@ -252,19 +252,19 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
|
||||
Span<float4x4> transforms = instances->transforms();
|
||||
if (STREQ(column_id.name, "Position")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
column_id.name, VArray<float3>::from_func(domain_num, [transforms](int64_t index) {
|
||||
column_id.name, VArray<float3>::from_std_func(domain_num, [transforms](int64_t index) {
|
||||
return transforms[index].location();
|
||||
}));
|
||||
}
|
||||
if (STREQ(column_id.name, "Rotation")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
column_id.name, VArray<float3>::from_func(domain_num, [transforms](int64_t index) {
|
||||
column_id.name, VArray<float3>::from_std_func(domain_num, [transforms](int64_t index) {
|
||||
return float3(math::to_euler(math::normalize(transforms[index])));
|
||||
}));
|
||||
}
|
||||
if (STREQ(column_id.name, "Scale")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
column_id.name, VArray<float3>::from_func(domain_num, [transforms](int64_t index) {
|
||||
column_id.name, VArray<float3>::from_std_func(domain_num, [transforms](int64_t index) {
|
||||
return math::to_scale<true>(transforms[index]);
|
||||
}));
|
||||
}
|
||||
@@ -277,7 +277,8 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
|
||||
if (domain_ == bke::AttrDomain::Layer && STREQ(column_id.name, "Name")) {
|
||||
const Span<const bke::greasepencil::Layer *> layers = grease_pencil->layers();
|
||||
return std::make_unique<ColumnValues>(
|
||||
column_id.name, VArray<std::string>::from_func(domain_num, [layers](int64_t index) {
|
||||
column_id.name,
|
||||
VArray<std::string>::from_std_func(domain_num, [layers](int64_t index) {
|
||||
StringRefNull name = layers[index]->name();
|
||||
if (name.is_empty()) {
|
||||
name = IFACE_("(Layer)");
|
||||
@@ -562,14 +563,14 @@ std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
|
||||
const int size = this->tot_rows();
|
||||
if (STREQ(column_id.name, "Grid Name")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
IFACE_("Grid Name"), VArray<std::string>::from_func(size, [volume](int64_t index) {
|
||||
IFACE_("Grid Name"), VArray<std::string>::from_std_func(size, [volume](int64_t index) {
|
||||
const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
|
||||
return volume_grid->name();
|
||||
}));
|
||||
}
|
||||
if (STREQ(column_id.name, "Data Type")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
IFACE_("Data Type"), VArray<std::string>::from_func(size, [volume](int64_t index) {
|
||||
IFACE_("Data Type"), VArray<std::string>::from_std_func(size, [volume](int64_t index) {
|
||||
const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
|
||||
const VolumeGridType type = volume_grid->grid_type();
|
||||
const char *name = nullptr;
|
||||
@@ -579,7 +580,7 @@ std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values(
|
||||
}
|
||||
if (STREQ(column_id.name, "Class")) {
|
||||
return std::make_unique<ColumnValues>(
|
||||
IFACE_("Class"), VArray<std::string>::from_func(size, [volume](int64_t index) {
|
||||
IFACE_("Class"), VArray<std::string>::from_std_func(size, [volume](int64_t index) {
|
||||
const bke::VolumeGridData *volume_grid = BKE_volume_grid_get(volume, index);
|
||||
openvdb::GridClass grid_class = volume_grid->grid_class();
|
||||
if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) {
|
||||
|
||||
Reference in New Issue
Block a user