From 1d4b4440d956bb7bdff46e12a42b6e1b57e387fd Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 19 Jun 2024 12:04:42 +0200 Subject: [PATCH] Curve: reduce overhead in debug builds --- source/blender/blenkernel/BKE_curves.hh | 21 +++++++++++++++++-- .../blenkernel/intern/curves_geometry.cc | 4 +++- source/blender/blenlib/BLI_offset_indices.hh | 10 +++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 96759451528..95acd2f160c 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -117,6 +117,14 @@ class CurvesGeometryRuntime { /** Stores weak references to material data blocks. */ std::unique_ptr bake_materials; + + /** + * Type counts have to be set eagerly after each operation. It's checked with asserts that the + * type counts are correct when accessed. However, this check is expensive and shouldn't be done + * all the time because it makes debug builds unusable in some situations that would be fine + * otherwise. + */ + bool check_type_counts = true; }; /** @@ -894,13 +902,22 @@ inline bool CurvesGeometry::has_curve_with_type(const Span types) con inline const std::array &CurvesGeometry::curve_type_counts() const { - BLI_assert(this->runtime->type_counts == calculate_type_counts(this->curve_types())); +#ifndef NDEBUG + + if (this->runtime->check_type_counts) { + const std::array actual_type_counts = calculate_type_counts( + this->curve_types()); + BLI_assert(this->runtime->type_counts == actual_type_counts); + this->runtime->check_type_counts = false; + } +#endif return this->runtime->type_counts; } inline OffsetIndices CurvesGeometry::points_by_curve() const { - return OffsetIndices({this->curve_offsets, this->curve_num + 1}); + return OffsetIndices({this->curve_offsets, this->curve_num + 1}, + offset_indices::NoSortCheck{}); } inline int CurvesGeometry::evaluated_points_num() const diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 2490537b2a7..290d902e7da 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -116,7 +116,8 @@ CurvesGeometry::CurvesGeometry(const CurvesGeometry &other) other.runtime->evaluated_length_cache, other.runtime->evaluated_tangent_cache, other.runtime->evaluated_normal_cache, - {}}); + {}, + true}); if (other.runtime->bake_materials) { this->runtime->bake_materials = std::make_unique( @@ -1065,6 +1066,7 @@ void CurvesGeometry::tag_topology_changed() this->tag_positions_changed(); this->runtime->evaluated_offsets_cache.tag_dirty(); this->runtime->nurbs_basis_cache.tag_dirty(); + this->runtime->check_type_counts = true; } void CurvesGeometry::tag_normals_changed() { diff --git a/source/blender/blenlib/BLI_offset_indices.hh b/source/blender/blenlib/BLI_offset_indices.hh index 825983957bd..0d47be49ea3 100644 --- a/source/blender/blenlib/BLI_offset_indices.hh +++ b/source/blender/blenlib/BLI_offset_indices.hh @@ -12,6 +12,9 @@ namespace blender::offset_indices { +/** Utility struct that can be passed into a function to skip a check for sorted indices. */ +struct NoSortCheck {}; + /** * References an array of ascending indices. A pair of consecutive indices encode an index range. * Another common way to store the same kind of data is to store the start and size of every range @@ -35,6 +38,13 @@ template class OffsetIndices { BLI_assert(offsets_.size() < 2 || std::is_sorted(offsets_.begin(), offsets_.end())); } + /** + * Same as above, but skips the debug check that indices are sorted, because that can have a + * high performance impact making debug builds unusable for files that would be fine otherwise. + * This can be used when it is known that the indices are sorted already. + */ + OffsetIndices(const Span offsets, NoSortCheck) : offsets_(offsets) {} + /** Return the total number of elements in the referenced arrays. */ T total_size() const {