diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 16:57:41 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-02-11 16:57:41 +0300 |
commit | 30f65b54a78edc2a974ba93fefa86534fe2b7ff4 (patch) | |
tree | 030cf43b7c2cbd649a2e8758bf319a5b76a29aef /source/blender/blenlib | |
parent | 9052c6fafa87654c9a45ce0d5b9ecee073ec1a5b (diff) | |
parent | 3657bb514130ce2d28c407432d6f10202a68c92a (diff) |
Merge branch 'master' into draw-colormanagementdraw-colormanagement
Diffstat (limited to 'source/blender/blenlib')
33 files changed, 826 insertions, 486 deletions
diff --git a/source/blender/blenlib/BLI_allocator.h b/source/blender/blenlib/BLI_allocator.h index 52fa8d2b705..075c181833c 100644 --- a/source/blender/blenlib/BLI_allocator.h +++ b/source/blender/blenlib/BLI_allocator.h @@ -30,12 +30,12 @@ */ #include <stdlib.h> +#include <algorithm> #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" #include "BLI_math_base.h" -#include "BLI_temporary_allocator.h" namespace BLI { @@ -52,7 +52,6 @@ class GuardedAllocator { void *allocate_aligned(uint size, uint alignment, const char *name) { - alignment = std::max<uint>(alignment, 8); return MEM_mallocN_aligned(size, alignment, name); } @@ -101,29 +100,6 @@ class RawAllocator { } }; -/** - * Use this only under specific circumstances as described in BLI_temporary_allocator.h. - */ -class TemporaryAllocator { - public: - void *allocate(uint size, const char *UNUSED(name)) - { - return BLI_temporary_allocate(size); - } - - void *allocate_aligned(uint size, uint alignment, const char *UNUSED(name)) - { - BLI_assert(alignment <= 64); - UNUSED_VARS_NDEBUG(alignment); - return BLI_temporary_allocate(size); - } - - void deallocate(void *ptr) - { - BLI_temporary_deallocate(ptr); - } -}; - } // namespace BLI #endif /* __BLI_ALLOCATOR_H__ */ diff --git a/source/blender/blenlib/BLI_array_cxx.h b/source/blender/blenlib/BLI_array_cxx.h index c7704e20fb1..adb00c95f28 100644 --- a/source/blender/blenlib/BLI_array_cxx.h +++ b/source/blender/blenlib/BLI_array_cxx.h @@ -27,26 +27,28 @@ #include "BLI_allocator.h" #include "BLI_array_ref.h" #include "BLI_memory_utils_cxx.h" +#include "BLI_index_range.h" namespace BLI { -template<typename T, typename Allocator = GuardedAllocator> class Array { +template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Array { private: T *m_data; uint m_size; Allocator m_allocator; + AlignedBuffer<sizeof(T) * N, alignof(T)> m_inline_storage; public: Array() { - m_data = nullptr; + m_data = this->inline_storage(); m_size = 0; } Array(ArrayRef<T> values) { m_size = values.size(); - m_data = this->allocate(m_size); + m_data = this->get_buffer_for_size(values.size()); uninitialized_copy_n(values.begin(), m_size, m_data); } @@ -56,8 +58,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { explicit Array(uint size) { - m_data = this->allocate(size); m_size = size; + m_data = this->get_buffer_for_size(size); for (uint i = 0; i < m_size; i++) { new (m_data + i) T(); @@ -66,8 +68,8 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { Array(uint size, const T &value) { - m_data = this->allocate(size); m_size = size; + m_data = this->get_buffer_for_size(size); uninitialized_fill_n(m_data, m_size, value); } @@ -76,30 +78,31 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { m_size = other.size(); m_allocator = other.m_allocator; - if (m_size == 0) { - m_data = nullptr; - return; - } - else { - m_data = this->allocate(m_size); - copy_n(other.begin(), m_size, m_data); - } + m_data = this->get_buffer_for_size(other.size()); + copy_n(other.begin(), m_size, m_data); } Array(Array &&other) noexcept { - m_data = other.m_data; m_size = other.m_size; m_allocator = other.m_allocator; - other.m_data = nullptr; + if (!other.uses_inline_storage()) { + m_data = other.m_data; + } + else { + m_data = this->get_buffer_for_size(m_size); + uninitialized_relocate_n(other.m_data, m_size, m_data); + } + + other.m_data = other.inline_storage(); other.m_size = 0; } ~Array() { destruct_n(m_data, m_size); - if (m_data != nullptr) { + if (!this->uses_inline_storage()) { m_allocator.deallocate((void *)m_data); } } @@ -141,12 +144,23 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { return *this; } + MutableArrayRef<T> as_mutable_ref() + { + return *this; + } + T &operator[](uint index) { BLI_assert(index < m_size); return m_data[index]; } + const T &operator[](uint index) const + { + BLI_assert(index < m_size); + return m_data[index]; + } + uint size() const { return m_size; @@ -182,15 +196,38 @@ template<typename T, typename Allocator = GuardedAllocator> class Array { return m_data + m_size; } + IndexRange index_range() const + { + return IndexRange(m_size); + } + private: + T *get_buffer_for_size(uint size) + { + if (size <= N) { + return this->inline_storage(); + } + else { + return this->allocate(size); + } + } + + T *inline_storage() const + { + return (T *)m_inline_storage.ptr(); + } + T *allocate(uint size) { return (T *)m_allocator.allocate_aligned( size * sizeof(T), std::alignment_of<T>::value, __func__); } -}; -template<typename T> using TemporaryArray = Array<T, TemporaryAllocator>; + bool uses_inline_storage() const + { + return m_data == this->inline_storage(); + } +}; } // namespace BLI diff --git a/source/blender/blenlib/BLI_array_ref.h b/source/blender/blenlib/BLI_array_ref.h index e34647676d8..6cc96cedc83 100644 --- a/source/blender/blenlib/BLI_array_ref.h +++ b/source/blender/blenlib/BLI_array_ref.h @@ -79,6 +79,16 @@ template<typename T> class ArrayRef { } /** + * ArrayRef<T *> -> ArrayRef<const T *> + * ArrayRef<Derived *> -> ArrayRef<Base *> + */ + template<typename U, + typename std::enable_if<std::is_convertible<U *, T>::value>::type * = nullptr> + ArrayRef(ArrayRef<U *> array) : ArrayRef((T *)array.begin(), array.size()) + { + } + + /** * Return a continuous part of the array. * Asserts that the slice stays within the array. */ @@ -247,14 +257,85 @@ template<typename T> class ArrayRef { } /** + * Check if the array contains duplicates. Does a linear search for every element. So the total + * running time is O(n^2). Only use this for small arrays. + */ + bool has_duplicates__linear_search() const + { + /* The size should really be smaller than that. If it is not, the calling code should be + * changed. */ + BLI_assert(m_size < 1000); + + for (uint i = 0; i < m_size; i++) { + const T &value = m_start[i]; + for (uint j = i + 1; j < m_size; j++) { + if (value == m_start[j]) { + return true; + } + } + } + return false; + } + + bool intersects__linear_search(ArrayRef other) const + { + /* The size should really be smaller than that. If it is not, the calling code should be + * changed. */ + BLI_assert(m_size < 1000); + + for (uint i = 0; i < m_size; i++) { + const T &value = m_start[i]; + if (other.contains(value)) { + return true; + } + } + return false; + } + + uint first_index(const T &search_value) const + { + int index = this->first_index_try(search_value); + BLI_assert(index >= 0); + return (uint)index; + } + + int first_index_try(const T &search_value) const + { + for (uint i = 0; i < m_size; i++) { + if (m_start[i] == search_value) { + return i; + } + } + return -1; + } + + template<typename PredicateT> bool any(const PredicateT predicate) + { + for (uint i = 0; i < m_size; i++) { + if (predicate(m_start[i])) { + return true; + } + } + return false; + } + + /** + * Utility to make it more convenient to iterate over all indices that can be used with this + * array. + */ + IndexRange index_range() const + { + return IndexRange(m_size); + } + + /** * Get a new array ref to the same underlying memory buffer. No conversions are done. - * Asserts when the sizes of the types don't match. */ template<typename NewT> ArrayRef<NewT> cast() const { - /* Can be adjusted to allow different type sizes when necessary. */ - BLI_STATIC_ASSERT(sizeof(T) == sizeof(NewT), ""); - return ArrayRef<NewT>((NewT *)m_start, m_size); + BLI_assert((m_size * sizeof(T)) % sizeof(NewT) == 0); + uint new_size = m_size * sizeof(T) / sizeof(NewT); + return ArrayRef<NewT>(reinterpret_cast<const NewT *>(m_start), new_size); } /** @@ -270,6 +351,11 @@ template<typename T> class ArrayRef { std::cout << '\n'; } } + + void print_as_lines(std::string name) const + { + this->print_as_lines(name, [](const T &value) { std::cout << value; }); + } }; /** @@ -300,7 +386,7 @@ template<typename T> class MutableArrayRef { { } - operator ArrayRef<T>() + operator ArrayRef<T>() const { return ArrayRef<T>(m_start, m_size); } @@ -411,6 +497,17 @@ template<typename T> class MutableArrayRef { { return ArrayRef<T>(m_start, m_size); } + + IndexRange index_range() const + { + return IndexRange(m_size); + } + + const T &last() const + { + BLI_assert(m_size > 0); + return m_start[m_size - 1]; + } }; /** @@ -421,6 +518,28 @@ template<typename T> ArrayRef<T> ref_c_array(const T *array, uint size) return ArrayRef<T>(array, size); } +template<typename T1, typename T2> void assert_same_size(const T1 &v1, const T2 &v2) +{ + UNUSED_VARS_NDEBUG(v1, v2); +#ifdef DEBUG + uint size = v1.size(); + BLI_assert(size == v1.size()); + BLI_assert(size == v2.size()); +#endif +} + +template<typename T1, typename T2, typename T3> +void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3) +{ + UNUSED_VARS_NDEBUG(v1, v2, v3); +#ifdef DEBUG + uint size = v1.size(); + BLI_assert(size == v1.size()); + BLI_assert(size == v2.size()); + BLI_assert(size == v3.size()); +#endif +} + } /* namespace BLI */ #endif /* __BLI_ARRAY_REF_H__ */ diff --git a/source/blender/blenlib/BLI_hash_cxx.h b/source/blender/blenlib/BLI_hash_cxx.h index e899f27c9ee..a369774a471 100644 --- a/source/blender/blenlib/BLI_hash_cxx.h +++ b/source/blender/blenlib/BLI_hash_cxx.h @@ -58,6 +58,7 @@ TRIVIAL_DEFAULT_INT_HASH(uint16_t); TRIVIAL_DEFAULT_INT_HASH(int32_t); TRIVIAL_DEFAULT_INT_HASH(uint32_t); TRIVIAL_DEFAULT_INT_HASH(int64_t); +TRIVIAL_DEFAULT_INT_HASH(uint64_t); template<> struct DefaultHash<float> { uint32_t operator()(float value) const diff --git a/source/blender/blenlib/BLI_index_range.h b/source/blender/blenlib/BLI_index_range.h index a1fed5bd97c..f67cc259227 100644 --- a/source/blender/blenlib/BLI_index_range.h +++ b/source/blender/blenlib/BLI_index_range.h @@ -31,6 +31,11 @@ #include "BLI_utildefines.h" +/* Forward declare tbb::blocked_range for conversion operations. */ +namespace tbb { +template<typename Value> class blocked_range; +} + namespace BLI { template<typename T> class ArrayRef; @@ -51,6 +56,11 @@ class IndexRange { { } + template<typename T> + IndexRange(const tbb::blocked_range<T> &range) : m_start(range.begin()), m_size(range.size()) + { + } + class Iterator { private: uint m_current; @@ -179,6 +189,11 @@ class IndexRange { return IndexRange(new_start, size); } + IndexRange slice(IndexRange range) const + { + return this->slice(range.start(), range.size()); + } + /** * Get read-only access to a memory buffer that contains the range as actual numbers. */ diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h index 9e966ffb798..9ba045fdbf8 100644 --- a/source/blender/blenlib/BLI_kdtree.h +++ b/source/blender/blenlib/BLI_kdtree.h @@ -17,6 +17,10 @@ #ifndef __BLI_KDTREE_H__ #define __BLI_KDTREE_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** \file * \ingroup bli * \brief A kd-tree for nearest neighbor search. @@ -66,4 +70,8 @@ #undef KDTreeNearest #undef KDTREE_PREFIX_ID +#ifdef __cplusplus +} +#endif + #endif /* __BLI_KDTREE_H__ */ diff --git a/source/blender/blenlib/BLI_listbase_wrapper.h b/source/blender/blenlib/BLI_listbase_wrapper.h index 34197fe9c45..d6832166e35 100644 --- a/source/blender/blenlib/BLI_listbase_wrapper.h +++ b/source/blender/blenlib/BLI_listbase_wrapper.h @@ -93,6 +93,19 @@ template<typename T> class IntrusiveListBaseWrapper { BLI_assert(ptr); return (T *)ptr; } + + uint index_of(const T *value) const + { + uint index = 0; + for (T *ptr : *this) { + if (ptr == value) { + return index; + } + index++; + } + BLI_assert(false); + return 0; + } }; } /* namespace BLI */ diff --git a/source/blender/blenlib/BLI_map.h b/source/blender/blenlib/BLI_map.h index 1edf7653c71..73b731252b6 100644 --- a/source/blender/blenlib/BLI_map.h +++ b/source/blender/blenlib/BLI_map.h @@ -413,6 +413,19 @@ template<typename KeyT, typename ValueT, typename Allocator = GuardedAllocator> return m_array.slots_set(); } + template<typename FuncT> void foreach_item(const FuncT &func) const + { + for (const Item &item : m_array) { + for (uint offset = 0; offset < 4; offset++) { + if (item.is_set(offset)) { + const KeyT &key = *item.key(offset); + const ValueT &value = *item.value(offset); + func(key, value); + } + } + } + } + void print_table() const { std::cout << "Hash Table:\n"; diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h index 2e756b14424..47bafff3a49 100644 --- a/source/blender/blenlib/BLI_math_color_blend.h +++ b/source/blender/blenlib/BLI_math_color_blend.h @@ -64,53 +64,49 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src2[4]); MINLINE void blend_color_overlay_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_hardlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); -MINLINE void blend_color_burn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); +MINLINE void blend_color_burn_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); MINLINE void blend_color_linearburn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_dodge_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_screen_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_softlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_pinlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_linearlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_vividlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_difference_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_exclusion_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_color_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); -MINLINE void blend_color_hue_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); +MINLINE void blend_color_hue_byte(unsigned char dst[4], const uchar src1[4], const uchar src2[4]); MINLINE void blend_color_saturation_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_luminosity_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]); + const uchar src1[4], + const uchar src2[4]); MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], diff --git a/source/blender/blenlib/BLI_memory_utils_cxx.h b/source/blender/blenlib/BLI_memory_utils_cxx.h index 22f333c6303..f15621b4e41 100644 --- a/source/blender/blenlib/BLI_memory_utils_cxx.h +++ b/source/blender/blenlib/BLI_memory_utils_cxx.h @@ -33,6 +33,11 @@ using std::uninitialized_copy_n; using std::uninitialized_fill; using std::uninitialized_fill_n; +template<typename T> void construct_default(T *ptr) +{ + new (ptr) T(); +} + template<typename T> void destruct(T *ptr) { ptr->~T(); @@ -79,6 +84,38 @@ template<typename T> void relocate_n(T *src, uint n, T *dst) destruct_n(src, n); } +template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args &&... args) +{ + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +} + +template<typename T> struct DestructValueAtAddress { + void operator()(T *ptr) + { + ptr->~T(); + } +}; + +template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddress<T>>; + +template<uint Size, uint Alignment> class alignas(Alignment) AlignedBuffer { + private: + /* Don't create an empty array. This causes problems with some compilers. */ + static constexpr uint ActualSize = (Size > 0) ? Size : 1; + char m_buffer[ActualSize]; + + public: + void *ptr() + { + return (void *)m_buffer; + } + + const void *ptr() const + { + return (const void *)m_buffer; + } +}; + } // namespace BLI #endif /* __BLI_MEMORY_UTILS_CXX_H__ */ diff --git a/source/blender/blenlib/BLI_open_addressing.h b/source/blender/blenlib/BLI_open_addressing.h index 8ca5156a952..a238902c631 100644 --- a/source/blender/blenlib/BLI_open_addressing.h +++ b/source/blender/blenlib/BLI_open_addressing.h @@ -70,7 +70,7 @@ class OpenAddressingArray { /* Can be used to map a hash value into the range of valid slot indices. */ uint32_t m_slot_mask; Allocator m_allocator; - char m_local_storage[sizeof(Item) * ItemsInSmallStorage]; + AlignedBuffer<sizeof(Item) * ItemsInSmallStorage, alignof(Item)> m_local_storage; public: explicit OpenAddressingArray(uint8_t item_exponent = 0) @@ -291,7 +291,7 @@ class OpenAddressingArray { private: Item *small_storage() const { - return reinterpret_cast<Item *>((char *)m_local_storage); + return reinterpret_cast<Item *>((char *)m_local_storage.ptr()); } bool is_in_small_storage() const diff --git a/source/blender/blenlib/BLI_optional.h b/source/blender/blenlib/BLI_optional.h new file mode 100644 index 00000000000..90bded604ea --- /dev/null +++ b/source/blender/blenlib/BLI_optional.h @@ -0,0 +1,199 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup bli + * + * Simple version of std::optional, which is only available since C++17. + */ + +#ifndef __BLI_OPTIONAL_H__ +#define __BLI_OPTIONAL_H__ + +#include "BLI_utildefines.h" +#include "BLI_memory_utils_cxx.h" + +#include <algorithm> +#include <memory> + +namespace BLI { + +template<typename T> class Optional { + private: + AlignedBuffer<sizeof(T), alignof(T)> m_storage; + bool m_set; + + public: + static Optional FromPointer(const T *ptr) + { + if (ptr == nullptr) { + return Optional(); + } + else { + return Optional(*ptr); + } + } + + Optional() : m_set(false) + { + } + + ~Optional() + { + this->reset(); + } + + Optional(const T &value) : Optional() + { + this->set(value); + } + + Optional(T &&value) : Optional() + { + this->set(std::forward<T>(value)); + } + + Optional(const Optional &other) : Optional() + { + if (other.has_value()) { + this->set(other.value()); + } + } + + Optional(Optional &&other) : Optional() + { + if (other.has_value()) { + this->set(std::move(other.value())); + } + } + + Optional &operator=(const Optional &other) + { + if (this == &other) { + return *this; + } + if (other.has_value()) { + this->set(other.value()); + } + else { + this->reset(); + } + return *this; + } + + Optional &operator=(Optional &&other) + { + if (this == &other) { + return *this; + } + if (other.has_value()) { + this->set(std::move(other.value())); + } + else { + this->reset(); + } + return *this; + } + + bool has_value() const + { + return m_set; + } + + const T &value() const + { + BLI_assert(m_set); + return *this->value_ptr(); + } + + T &value() + { + BLI_assert(m_set); + return *this->value_ptr(); + } + + void set(const T &value) + { + if (m_set) { + this->value() = value; + } + else { + new (this->value_ptr()) T(value); + m_set = true; + } + } + + void set(T &&value) + { + if (m_set) { + this->value() = std::move(value); + } + else { + new (this->value_ptr()) T(std::move(value)); + m_set = true; + } + } + + void set_new(const T &value) + { + BLI_assert(!m_set); + new (this->value_ptr()) T(value); + m_set = true; + } + + void set_new(T &&value) + { + BLI_assert(!m_set); + new (this->value_ptr()) T(std::move(value)); + m_set = true; + } + + void reset() + { + if (m_set) { + this->value_ptr()->~T(); + m_set = false; + } + } + + T extract() + { + BLI_assert(m_set); + T value = std::move(this->value()); + this->reset(); + return value; + } + + T *operator->() + { + return this->value_ptr(); + } + + T &operator*() + { + return *this->value_ptr(); + } + + private: + T *value_ptr() const + { + return (T *)m_storage.ptr(); + } +}; + +} /* namespace BLI */ + +#endif /* __BLI_OPTIONAL_H__ */ diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index be2b18b05fd..ad8a90b3977 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -20,6 +20,8 @@ #ifndef __BLI_RAND_H__ #define __BLI_RAND_H__ +#include "BLI_compiler_attrs.h" + /** \file * \ingroup bli * \brief Random number functions. diff --git a/source/blender/blenlib/BLI_stack_cxx.h b/source/blender/blenlib/BLI_stack_cxx.h index 7915acadfac..a26318a3dcb 100644 --- a/source/blender/blenlib/BLI_stack_cxx.h +++ b/source/blender/blenlib/BLI_stack_cxx.h @@ -58,7 +58,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St /** * Return true when the stack is empty, otherwise false. */ - bool empty() const + bool is_empty() const { return this->size() == 0; } @@ -76,6 +76,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St m_elements.append(std::move(value)); } + void push_multiple(ArrayRef<T> values) + { + m_elements.extend(values); + } + /** * Remove the element from the top of the stack and return it. * This will assert when the stack is empty. @@ -91,7 +96,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class St */ T &peek() { - BLI_assert(!this->empty()); + BLI_assert(!this->is_empty()); return m_elements[this->size() - 1]; } diff --git a/source/blender/blenlib/BLI_string_map.h b/source/blender/blenlib/BLI_string_map.h index ba870eb878a..2f09e489a7a 100644 --- a/source/blender/blenlib/BLI_string_map.h +++ b/source/blender/blenlib/BLI_string_map.h @@ -30,6 +30,7 @@ #include "BLI_map.h" #include "BLI_string_ref.h" #include "BLI_vector.h" +#include "BLI_optional.h" namespace BLI { @@ -190,6 +191,22 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap { } /** + * Add a new element to the map if the key does not exist yet. + */ + void add(StringRef key, const T &value) + { + if (!this->contains(key)) { + this->add_new(key, value); + } + } + void add(StringRef key, T &&value) + { + if (!this->contains(key)) { + this->add_new(key, std::move(value)); + } + } + + /** * Return true when the key exists in the map, otherwise false. */ bool contains(StringRef key) const @@ -263,6 +280,11 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap { return const_cast<T *>(const_cast<const StringMap *>(this)->lookup_ptr(key)); } + Optional<T> try_lookup(StringRef key) const + { + return Optional<T>::FromPointer(this->lookup_ptr(key)); + } + /** * Get a copy of the value corresponding to the key. If the key does not exist, return the * default value. @@ -326,7 +348,7 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap { /** * Run a function for every key-value-pair in the map. */ - template<typename FuncT> void foreach_key_value_pair(const FuncT &func) + template<typename FuncT> void foreach_item(const FuncT &func) { for (Item &item : m_array) { for (uint offset = 0; offset < 4; offset++) { @@ -339,6 +361,19 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap { } } + template<typename FuncT> void foreach_item(const FuncT &func) const + { + for (const Item &item : m_array) { + for (uint offset = 0; offset < 4; offset++) { + if (item.is_set(offset)) { + StringRefNull key = item.get_key(offset, m_chars); + const T &value = *item.value(offset); + func(key, value); + } + } + } + } + private: uint32_t compute_string_hash(StringRef key) const { @@ -415,6 +450,15 @@ template<typename T, typename Allocator = GuardedAllocator> class StringMap { } ITER_SLOTS_END(offset); } + + template<typename ForwardT> void add__impl(StringRef key, ForwardT &&value) + { + this->ensure_can_add(); + uint32_t hash = this->compute_string_hash(key); + ITER_SLOTS_BEGIN (hash, m_array, , item, offset) { + } + ITER_SLOTS_END(offset); + } }; #undef ITER_SLOTS_BEGIN diff --git a/source/blender/blenlib/BLI_string_ref.h b/source/blender/blenlib/BLI_string_ref.h index 76163a2754c..54c2f0e7209 100644 --- a/source/blender/blenlib/BLI_string_ref.h +++ b/source/blender/blenlib/BLI_string_ref.h @@ -109,6 +109,8 @@ class StringRefBase { * Returns true when the string ends with the given suffix. Otherwise false. */ bool endswith(StringRef suffix) const; + + StringRef substr(uint start, uint size) const; }; /** @@ -242,6 +244,12 @@ inline bool StringRefBase::endswith(StringRef suffix) const return true; } +inline StringRef StringRefBase::substr(uint start, uint size) const +{ + BLI_assert(start + size <= m_size); + return StringRef(m_data + start, size); +} + } // namespace BLI #endif /* __BLI_STRING_REF_H__ */ diff --git a/source/blender/blenlib/BLI_string_utils.h b/source/blender/blenlib/BLI_string_utils.h index 13dbb2de659..b3aed438641 100644 --- a/source/blender/blenlib/BLI_string_utils.h +++ b/source/blender/blenlib/BLI_string_utils.h @@ -44,6 +44,11 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, cons void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len); /* Join strings, return newly allocated string. */ +char *BLI_string_join_array(char *result, + size_t result_len, + const char *strings[], + uint strings_len) ATTR_NONNULL(); + char *BLI_string_join_arrayN(const char *strings[], uint strings_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); char *BLI_string_join_array_by_sep_charN(char sep, @@ -54,6 +59,9 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep, const char *strings[], uint strings_len) ATTR_NONNULL(); /* Take multiple arguments, pass as (array, length). */ +#define BLI_string_join(result, result_len, ...) \ + BLI_string_join_array( \ + result, result_len, ((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__)) #define BLI_string_joinN(...) \ BLI_string_join_arrayN(((const char *[]){__VA_ARGS__}), VA_NARGS_COUNT(__VA_ARGS__)) #define BLI_string_join_by_sep_charN(sep, ...) \ diff --git a/source/blender/blenlib/BLI_temporary_allocator.h b/source/blender/blenlib/BLI_temporary_allocator.h deleted file mode 100644 index b378e5869c0..00000000000 --- a/source/blender/blenlib/BLI_temporary_allocator.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup bli - * - * This allocation method assumes - * 1. The allocations are short-lived. - * 2. The total number of allocations is bound by a constant per thread. - * - * These two assumptions make it possible to cache and reuse relatively large buffers. They allow - * to hand out buffers that are much larger than the requested size, without the fear of running - * out of memory. - * - * The assumptions might feel a bit limiting at first, but hold true in many cases. For example, - * many algorithms need to store temporary data. With this allocator, the allocation can become - * very cheap for common cases. - * - * Many cpu-bound algorithms can benefit from being split up into several stages, whereby the - * output of one stage is written into an array that is read by the next stage. This makes them - * easier to debug, profile and optimize. Often a reason this is not done is that the memory - * allocation might be expensive. The goal of this allocator is to make this a non-issue, by - * reusing the same long buffers over and over again. - * - * All allocated buffers are 64 byte aligned, to make them as reusable as possible. - * If the requested size is too large, there is a fallback to normal allocation. The allocation - * overhead is probably very small in these cases anyway. - * - * The best way to use this allocator is to use one of the prepared containers like TemporaryVector - * and TemporaryArray. - */ - -#ifndef __BLI_TEMPORARY_ALLOCATOR_H__ -#define __BLI_TEMPORARY_ALLOCATOR_H__ - -#include "BLI_utildefines.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLI_TEMPORARY_BUFFER_ALIGNMENT 64 - -void *BLI_temporary_allocate(uint size); -void BLI_temporary_deallocate(void *buffer); - -#ifdef __cplusplus -} -#endif - -#endif /* __BLI_TEMPORARY_ALLOCATOR_H__ */ diff --git a/source/blender/blenlib/BLI_temporary_allocator_cxx.h b/source/blender/blenlib/BLI_temporary_allocator_cxx.h deleted file mode 100644 index 06159f68059..00000000000 --- a/source/blender/blenlib/BLI_temporary_allocator_cxx.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __BLI_TEMPORARY_ALLOCATOR_CXX_H__ -#define __BLI_TEMPORARY_ALLOCATOR_CXX_H__ - -/** \file - * \ingroup bli - */ - -#include "BLI_temporary_allocator.h" - -namespace BLI { - -template<typename T> class MutableArrayRef; - -template<typename T> MutableArrayRef<T> temporary_allocate_array(uint size) -{ - void *ptr = BLI_temporary_allocate(sizeof(T) * size); - return MutableArrayRef<T>((T *)ptr, size); -} - -}; // namespace BLI - -#endif /* __BLI_TEMPORARY_ALLOCATOR_CXX_H__ */ diff --git a/source/blender/blenlib/BLI_utility_mixins.h b/source/blender/blenlib/BLI_utility_mixins.h new file mode 100644 index 00000000000..ce7a4ce094a --- /dev/null +++ b/source/blender/blenlib/BLI_utility_mixins.h @@ -0,0 +1,52 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup bli + */ + +#ifndef __BLI_UTILITY_MIXINS_H__ +#define __BLI_UTILITY_MIXINS_H__ + +namespace BLI { + +class NonCopyable { + public: + /* Disable copy construction and assignment. */ + NonCopyable(const NonCopyable &other) = delete; + NonCopyable &operator=(const NonCopyable &other) = delete; + + /* Explicitly enable default construction, move construction and move assignment. */ + NonCopyable() = default; + NonCopyable(NonCopyable &&other) = default; + NonCopyable &operator=(NonCopyable &&other) = default; +}; + +class NonMovable { + public: + /* Disable move construction and assignment. */ + NonMovable(NonMovable &&other) = delete; + NonMovable &operator=(NonMovable &&other) = delete; + + /* Explicitly enable default construction, copy construction and copy assignment. */ + NonMovable() = default; + NonMovable(const NonMovable &other) = default; + NonMovable &operator=(const NonMovable &other) = default; +}; + +} // namespace BLI + +#endif /* __BLI_UTILITY_MIXINS_H__ */ diff --git a/source/blender/blenlib/BLI_vector.h b/source/blender/blenlib/BLI_vector.h index 46c46a1440f..60251347795 100644 --- a/source/blender/blenlib/BLI_vector.h +++ b/source/blender/blenlib/BLI_vector.h @@ -37,6 +37,7 @@ #include "BLI_listbase_wrapper.h" #include "BLI_math_base.h" #include "BLI_allocator.h" +#include "BLI_index_range.h" #include "MEM_guardedalloc.h" @@ -48,7 +49,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve T *m_end; T *m_capacity_end; Allocator m_allocator; - char m_small_buffer[sizeof(T) * N]; + AlignedBuffer<sizeof(T) * N, alignof(T)> m_small_buffer; #ifndef NDEBUG /* Storing size in debug builds, because it makes debugging much easier sometimes. */ @@ -215,6 +216,16 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve return MutableArrayRef<T>(m_begin, this->size()); } + ArrayRef<T> as_ref() const + { + return *this; + } + + MutableArrayRef<T> as_mutable_ref() + { + return *this; + } + Vector &operator=(const Vector &other) { if (this == &other) { @@ -233,6 +244,8 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve return *this; } + /* This can fail, when the vector is used to build a recursive data structure. + See https://youtu.be/7Qgd9B1KuMQ?t=840. */ this->~Vector(); new (this) Vector(std::move(other)); @@ -293,6 +306,20 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve this->append_unchecked(std::move(value)); } + uint append_and_get_index(const T &value) + { + uint index = this->size(); + this->append(value); + return index; + } + + void append_non_duplicates(const T &value) + { + if (!this->contains(value)) { + this->append(value); + } + } + void append_unchecked(const T &value) { BLI_assert(m_end < m_capacity_end); @@ -341,6 +368,13 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve this->extend_unchecked(start, amount); } + void extend_non_duplicates(ArrayRef<T> array) + { + for (const T &value : array) { + this->append_non_duplicates(value); + } + } + void extend_unchecked(ArrayRef<T> array) { this->extend_unchecked(array.begin(), array.size()); @@ -441,11 +475,17 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve UPDATE_VECTOR_SIZE(this); } + void remove_first_occurrence_and_reorder(const T &value) + { + uint index = this->index(value); + this->remove_and_reorder((uint)index); + } + /** * Do a linear search to find the value in the vector. * When found, return the first index, otherwise return -1. */ - int index(const T &value) const + int index_try(const T &value) const { for (T *current = m_begin; current != m_end; current++) { if (*current == value) { @@ -456,12 +496,23 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve } /** + * Do a linear search to find the value in the vector. + * When found, return the first index, otherwise fail. + */ + uint index(const T &value) const + { + int index = this->index_try(value); + BLI_assert(index >= 0); + return (uint)index; + } + + /** * Do a linear search to see of the value is in the vector. * Return true when it exists, otherwise false. */ bool contains(const T &value) const { - return this->index(value) != -1; + return this->index_try(value) != -1; } /** @@ -520,6 +571,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve return (uint)(m_capacity_end - m_begin); } + IndexRange index_range() const + { + return IndexRange(this->size()); + } + void print_stats() const { std::cout << "Small Vector at " << (void *)this << ":" << std::endl; @@ -531,7 +587,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve private: T *small_buffer() const { - return (T *)m_small_buffer; + return (T *)m_small_buffer.ptr(); } bool is_small() const @@ -555,10 +611,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve /* Round up to the next power of two. Otherwise consecutive calls to grow can cause a * reallocation every time even though the min_capacity only increments. */ min_capacity = power_of_2_max_u(min_capacity); + uint size = this->size(); T *new_array = (T *)m_allocator.allocate_aligned( - min_capacity * (uint)sizeof(T), std::alignment_of<T>::value, __func__); + min_capacity * (uint)sizeof(T), std::alignment_of<T>::value, "grow BLI::Vector"); uninitialized_relocate_n(m_begin, size, new_array); if (!this->is_small()) { @@ -600,7 +657,11 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve #undef UPDATE_VECTOR_SIZE -template<typename T, uint N = 4> using TemporaryVector = Vector<T, N, TemporaryAllocator>; +/** + * Use when the vector is used in the local scope of a function. It has a larger inline storage by + * default to make allocations less likely. + */ +template<typename T, uint N = 20> using ScopedVector = Vector<T, N, GuardedAllocator>; } /* namespace BLI */ diff --git a/source/blender/blenlib/BLI_vector_set.h b/source/blender/blenlib/BLI_vector_set.h index fb21f7ed987..99d955c60d8 100644 --- a/source/blender/blenlib/BLI_vector_set.h +++ b/source/blender/blenlib/BLI_vector_set.h @@ -292,12 +292,12 @@ template<typename T, typename Allocator = GuardedAllocator> class VectorSet { return m_elements[index]; } - operator ArrayRef<T>() const + ArrayRef<T> as_ref() const { - return m_elements; + return *this; } - operator MutableArrayRef<T>() + operator ArrayRef<T>() const { return m_elements; } diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index d22b1cd0ddb..1e4e07d63b3 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -52,7 +52,6 @@ set(SRC intern/BLI_memblock.c intern/BLI_memiter.c intern/BLI_mempool.c - intern/BLI_temporary_allocator.cc intern/BLI_timer.c intern/DLRB_tree.c intern/array_store.c @@ -213,6 +212,7 @@ set(SRC BLI_mempool.h BLI_noise.h BLI_open_addressing.h + BLI_optional.h BLI_path_util.h BLI_polyfill_2d.h BLI_polyfill_2d_beautify.h @@ -236,8 +236,6 @@ set(SRC BLI_sys_types.h BLI_system.h BLI_task.h - BLI_temporary_allocator.h - BLI_temporary_allocator_cxx.h BLI_threads.h BLI_timecode.h BLI_timer.h @@ -245,6 +243,7 @@ set(SRC BLI_utildefines_iter.h BLI_utildefines_stack.h BLI_utildefines_variadic.h + BLI_utility_mixins.h BLI_uvproject.h BLI_vector.h BLI_vector_set.h diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 05ffb02597d..1c518cf1487 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -220,8 +220,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) if (nbuckets > nbuckets_old) { for (i = 0; i < nbuckets_old; i++) { for (Entry *e = buckets_old[i], *e_next; e; e = e_next) { - const unsigned hash = ghash_entryhash(gh, e); - const unsigned bucket_index = ghash_bucket_index(gh, hash); + const uint hash = ghash_entryhash(gh, e); + const uint bucket_index = ghash_bucket_index(gh, hash); e_next = e->next; e->next = buckets_new[bucket_index]; buckets_new[bucket_index] = e; @@ -232,8 +232,8 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) for (i = 0; i < nbuckets_old; i++) { #ifdef GHASH_USE_MODULO_BUCKETS for (Entry *e = buckets_old[i], *e_next; e; e = e_next) { - const unsigned hash = ghash_entryhash(gh, e); - const unsigned bucket_index = ghash_bucket_index(gh, hash); + const uint hash = ghash_entryhash(gh, e); + const uint bucket_index = ghash_bucket_index(gh, hash); e_next = e->next; e->next = buckets_new[bucket_index]; buckets_new[bucket_index] = e; @@ -241,7 +241,7 @@ static void ghash_buckets_resize(GHash *gh, const uint nbuckets) #else /* No need to recompute hashes in this case, since our mask is just smaller, * all items in old bucket 'i' will go in same new bucket (i & new_mask)! */ - const unsigned bucket_index = ghash_bucket_index(gh, i); + const uint bucket_index = ghash_bucket_index(gh, i); BLI_assert(!buckets_old[i] || (bucket_index == ghash_bucket_index(gh, ghash_entryhash(gh, buckets_old[i])))); Entry *e; diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc index fde4dcf6d41..6421eb0794b 100644 --- a/source/blender/blenlib/intern/BLI_index_range.cc +++ b/source/blender/blenlib/intern/BLI_index_range.cc @@ -24,7 +24,7 @@ namespace BLI { -static Vector<Array<uint, RawAllocator>, 1, RawAllocator> arrays; +static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays; static uint current_array_size = 0; static uint *current_array = nullptr; static std::mutex current_array_mutex; @@ -44,7 +44,7 @@ ArrayRef<uint> IndexRange::as_array_ref() const } uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size)); - Array<uint, RawAllocator> new_array(new_size); + Array<uint, 0, RawAllocator> new_array(new_size); for (uint i = 0; i < new_size; i++) { new_array[i] = i; } diff --git a/source/blender/blenlib/intern/BLI_temporary_allocator.cc b/source/blender/blenlib/intern/BLI_temporary_allocator.cc deleted file mode 100644 index b145e65530d..00000000000 --- a/source/blender/blenlib/intern/BLI_temporary_allocator.cc +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <mutex> -#include <stack> - -#include "BLI_temporary_allocator.h" -#include "BLI_stack_cxx.h" - -using namespace BLI; - -constexpr uint ALIGNMENT = BLI_TEMPORARY_BUFFER_ALIGNMENT; -constexpr uint SMALL_BUFFER_SIZE = 64 * 1024; -constexpr uintptr_t ALIGNMENT_MASK = ~(uintptr_t)(ALIGNMENT - 1); - -enum TemporaryBufferType { - Small, - Large, -}; - -struct MemHead { - void *raw_ptr; - TemporaryBufferType type; -}; - -static MemHead &get_memhead(void *aligned_ptr) -{ - return *((MemHead *)aligned_ptr - 1); -} - -static void *raw_allocate(uint size) -{ - uint total_allocation_size = size + ALIGNMENT + sizeof(MemHead); - - uintptr_t raw_ptr = (uintptr_t)malloc(total_allocation_size); - uintptr_t aligned_ptr = (raw_ptr + ALIGNMENT + sizeof(MemHead)) & ALIGNMENT_MASK; - - MemHead &memhead = get_memhead((void *)aligned_ptr); - memhead.raw_ptr = (void *)raw_ptr; - return (void *)aligned_ptr; -} - -static void raw_deallocate(void *ptr) -{ - BLI_assert(((uintptr_t)ptr & ~ALIGNMENT_MASK) == 0); - MemHead &memhead = get_memhead(ptr); - void *raw_ptr = memhead.raw_ptr; - free(raw_ptr); -} - -struct ThreadLocalBuffers { - uint allocated_amount = 0; - Stack<void *, 32, RawAllocator> buffers; - - ~ThreadLocalBuffers() - { - for (void *ptr : buffers) { - raw_deallocate(ptr); - } - } -}; - -static thread_local ThreadLocalBuffers local_storage; - -void *BLI_temporary_allocate(uint size) -{ - /* The total amount of allocated buffers using this allocator should be limited by a constant. If - * it grows unbounded, there is likely a memory leak somewhere. */ - BLI_assert(local_storage.allocated_amount < 100); - - if (size <= SMALL_BUFFER_SIZE) { - auto &buffers = local_storage.buffers; - if (buffers.empty()) { - void *ptr = raw_allocate(SMALL_BUFFER_SIZE); - MemHead &memhead = get_memhead(ptr); - memhead.type = TemporaryBufferType::Small; - local_storage.allocated_amount++; - return ptr; - } - else { - return buffers.pop(); - } - } - else { - void *ptr = raw_allocate(size); - MemHead &memhead = get_memhead(ptr); - memhead.type = TemporaryBufferType::Large; - return ptr; - } -} - -void BLI_temporary_deallocate(void *buffer) -{ - MemHead &memhead = get_memhead(buffer); - if (memhead.type == TemporaryBufferType::Small) { - auto &buffers = local_storage.buffers; - buffers.push(buffer); - } - else { - raw_deallocate(buffer); - } -} diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c index 118949d1c46..7287bec0849 100644 --- a/source/blender/blenlib/intern/delaunay_2d.c +++ b/source/blender/blenlib/intern/delaunay_2d.c @@ -389,7 +389,6 @@ static CDTEdge *connect_separate_parts(CDT_state *cdt, SymEdge *se1, SymEdge *se { CDTEdge *e; SymEdge *se1_rot, *se1_rotsym, *se2_rot, *se2_rotsym, *new_se, *new_se_sym; - ; BLI_assert(se1->face == cdt->outer_face && se2->face == cdt->outer_face); se1_rot = se1->rot; @@ -1735,7 +1734,7 @@ static bool can_collapse(const SymEdge *se) * edges may end up with zero or negative area (see can_collapse, above). * So don't choose a collapse direction that is not allowed or one that has an original vertex * as origin and a non-original vertex as destination. - * If both collapse directions are allowed by that rule, picke the one with the lower original + * If both collapse directions are allowed by that rule, pick the one with the lower original * index. * * After merging, the faces abc and adb disappear (if they are not the outer face). diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index a1c88edca6f..0a496d2bd68 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -224,7 +224,7 @@ MINLINE unsigned int power_of_2_max_u(unsigned int x) return x + 1; } -MINLINE unsigned power_of_2_min_u(unsigned x) +MINLINE unsigned int power_of_2_min_u(unsigned int x) { x |= (x >> 1); x |= (x >> 2); diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c index 7241779b32a..eb82bb81a89 100644 --- a/source/blender/blenlib/intern/math_color_blend_inline.c +++ b/source/blender/blenlib/intern/math_color_blend_inline.c @@ -49,9 +49,7 @@ /* straight alpha byte blending modes */ -MINLINE void blend_color_mix_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_mix_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight over operation */ @@ -64,10 +62,10 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4], tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]); tmp[3] = (mt * src1[3]) + (t * 255); - dst[0] = (unsigned char)divide_round_i(tmp[0], tmp[3]); - dst[1] = (unsigned char)divide_round_i(tmp[1], tmp[3]); - dst[2] = (unsigned char)divide_round_i(tmp[2], tmp[3]); - dst[3] = (unsigned char)divide_round_i(tmp[3], 255); + dst[0] = (uchar)divide_round_i(tmp[0], tmp[3]); + dst[1] = (uchar)divide_round_i(tmp[1], tmp[3]); + dst[2] = (uchar)divide_round_i(tmp[2], tmp[3]); + dst[3] = (uchar)divide_round_i(tmp[3], 255); } else { /* no op */ @@ -75,9 +73,7 @@ MINLINE void blend_color_mix_byte(unsigned char dst[4], } } -MINLINE void blend_color_add_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_add_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight add operation */ @@ -88,9 +84,9 @@ MINLINE void blend_color_add_byte(unsigned char dst[4], tmp[1] = (src1[1] * 255) + (src2[1] * t); tmp[2] = (src1[2] * 255) + (src2[2] * t); - dst[0] = (unsigned char)min_ii(divide_round_i(tmp[0], 255), 255); - dst[1] = (unsigned char)min_ii(divide_round_i(tmp[1], 255), 255); - dst[2] = (unsigned char)min_ii(divide_round_i(tmp[2], 255), 255); + dst[0] = (uchar)min_ii(divide_round_i(tmp[0], 255), 255); + dst[1] = (uchar)min_ii(divide_round_i(tmp[1], 255), 255); + dst[2] = (uchar)min_ii(divide_round_i(tmp[2], 255), 255); dst[3] = src1[3]; } else { @@ -99,9 +95,7 @@ MINLINE void blend_color_add_byte(unsigned char dst[4], } } -MINLINE void blend_color_sub_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_sub_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight sub operation */ @@ -112,9 +106,9 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4], tmp[1] = (src1[1] * 255) - (src2[1] * t); tmp[2] = (src1[2] * 255) - (src2[2] * t); - dst[0] = (unsigned char)max_ii(divide_round_i(tmp[0], 255), 0); - dst[1] = (unsigned char)max_ii(divide_round_i(tmp[1], 255), 0); - dst[2] = (unsigned char)max_ii(divide_round_i(tmp[2], 255), 0); + dst[0] = (uchar)max_ii(divide_round_i(tmp[0], 255), 0); + dst[1] = (uchar)max_ii(divide_round_i(tmp[1], 255), 0); + dst[2] = (uchar)max_ii(divide_round_i(tmp[2], 255), 0); dst[3] = src1[3]; } else { @@ -123,9 +117,7 @@ MINLINE void blend_color_sub_byte(unsigned char dst[4], } } -MINLINE void blend_color_mul_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_mul_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight multiply operation */ @@ -137,9 +129,9 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4], tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]); tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255 * 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255 * 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255 * 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255 * 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255 * 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255 * 255); dst[3] = src1[3]; } else { @@ -148,9 +140,7 @@ MINLINE void blend_color_mul_byte(unsigned char dst[4], } } -MINLINE void blend_color_lighten_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_lighten_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight lighten operation */ @@ -162,9 +152,9 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1])); tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2])); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255); dst[3] = src1[3]; } else { @@ -173,9 +163,7 @@ MINLINE void blend_color_lighten_byte(unsigned char dst[4], } } -MINLINE void blend_color_darken_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_darken_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight darken operation */ @@ -187,9 +175,9 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4], tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1])); tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2])); - dst[0] = (unsigned char)divide_round_i(tmp[0], 255); - dst[1] = (unsigned char)divide_round_i(tmp[1], 255); - dst[2] = (unsigned char)divide_round_i(tmp[2], 255); + dst[0] = (uchar)divide_round_i(tmp[0], 255); + dst[1] = (uchar)divide_round_i(tmp[1], 255); + dst[2] = (uchar)divide_round_i(tmp[2], 255); dst[3] = src1[3]; } else { @@ -198,9 +186,7 @@ MINLINE void blend_color_darken_byte(unsigned char dst[4], } } -MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_erase_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight so just modify alpha channel */ @@ -209,7 +195,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], dst[0] = src1[0]; dst[1] = src1[1]; dst[2] = src1[2]; - dst[3] = (unsigned char)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0); + dst[3] = (uchar)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0); } else { /* no op */ @@ -217,9 +203,7 @@ MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], } } -MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4]) +MINLINE void blend_color_add_alpha_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { if (src2[3] != 0) { /* straight so just modify alpha channel */ @@ -228,7 +212,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], dst[0] = src1[0]; dst[1] = src1[1]; dst[2] = src1[2]; - dst[3] = (unsigned char)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255); + dst[3] = (uchar)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255); } else { /* no op */ @@ -236,9 +220,7 @@ MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], } } -MINLINE void blend_color_overlay_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_overlay_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = (int)src2[3]; if (fac != 0) { @@ -254,7 +236,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4], else { temp = (2 * src1[i] * src2[i]) >> 8; } - dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255); } } else { @@ -263,9 +245,7 @@ MINLINE void blend_color_overlay_byte(unsigned char dst[4], } } -MINLINE void blend_color_hardlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_hardlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = (int)src2[3]; if (fac != 0) { @@ -281,7 +261,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4], else { temp = (2 * src2[i] * src1[i]) >> 8; } - dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255); + dst[i] = (uchar)min_ii((temp * fac + src1[i] * mfac) / 255, 255); } } else { @@ -290,9 +270,7 @@ MINLINE void blend_color_hardlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_burn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_burn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -301,7 +279,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4], while (i--) { const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -310,9 +288,7 @@ MINLINE void blend_color_burn_byte(unsigned char dst[4], } } -MINLINE void blend_color_linearburn_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_linearburn_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -321,7 +297,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4], while (i--) { const int temp = max_ii(src1[i] + src2[i] - 255, 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -330,9 +306,7 @@ MINLINE void blend_color_linearburn_byte(unsigned char dst[4], } } -MINLINE void blend_color_dodge_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_dodge_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -341,7 +315,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4], while (i--) { const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -350,9 +324,7 @@ MINLINE void blend_color_dodge_byte(unsigned char dst[4], } } -MINLINE void blend_color_screen_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_screen_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -361,7 +333,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4], while (i--) { const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -370,9 +342,7 @@ MINLINE void blend_color_screen_byte(unsigned char dst[4], } } -MINLINE void blend_color_softlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_softlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -388,7 +358,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4], else { temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -397,9 +367,7 @@ MINLINE void blend_color_softlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_pinlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_pinlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -415,7 +383,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4], else { temp = min_ii(2 * src2[i], src1[i]); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -424,9 +392,7 @@ MINLINE void blend_color_pinlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_linearlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_linearlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -442,7 +408,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4], else { temp = max_ii(src1[i] + 2 * src2[i] - 255, 0); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -451,9 +417,7 @@ MINLINE void blend_color_linearlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_vividlight_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_vividlight_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -475,7 +439,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], else { temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0); } - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -484,9 +448,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], } } -MINLINE void blend_color_difference_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_difference_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -495,7 +457,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4], while (i--) { const int temp = abs(src1[i] - src2[i]); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -504,9 +466,7 @@ MINLINE void blend_color_difference_byte(unsigned char dst[4], } } -MINLINE void blend_color_exclusion_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_exclusion_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -515,7 +475,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4], while (i--) { const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255); - dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255); + dst[i] = (uchar)((temp * fac + src1[i] * mfac) / 255); } } else { @@ -524,9 +484,7 @@ MINLINE void blend_color_exclusion_byte(unsigned char dst[4], } } -MINLINE void blend_color_color_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_color_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -542,9 +500,9 @@ MINLINE void blend_color_color_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -552,9 +510,7 @@ MINLINE void blend_color_color_byte(unsigned char dst[4], } } -MINLINE void blend_color_hue_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_hue_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -569,9 +525,9 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -579,9 +535,7 @@ MINLINE void blend_color_hue_byte(unsigned char dst[4], } } -MINLINE void blend_color_saturation_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_saturation_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -598,9 +552,9 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -608,9 +562,7 @@ MINLINE void blend_color_saturation_byte(unsigned char dst[4], } } -MINLINE void blend_color_luminosity_byte(unsigned char dst[4], - unsigned const char src1[4], - unsigned const char src2[4]) +MINLINE void blend_color_luminosity_byte(uchar dst[4], const uchar src1[4], const uchar src2[4]) { const int fac = src2[3]; if (fac != 0) { @@ -625,9 +577,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4], hsv_to_rgb(h1, s1, v1, &r, &g, &b); - dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); - dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); - dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); + dst[0] = (uchar)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255); + dst[1] = (uchar)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255); + dst[2] = (uchar)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255); } else { /* no op */ @@ -635,9 +587,9 @@ MINLINE void blend_color_luminosity_byte(unsigned char dst[4], } } -MINLINE void blend_color_interpolate_byte(unsigned char dst[4], - const unsigned char src1[4], - const unsigned char src2[4], +MINLINE void blend_color_interpolate_byte(uchar dst[4], + const uchar src1[4], + const uchar src2[4], float ft) { /* do color interpolation, but in premultiplied space so that RGB colors @@ -647,10 +599,10 @@ MINLINE void blend_color_interpolate_byte(unsigned char dst[4], int tmp = (mt * src1[3] + t * src2[3]); if (tmp > 0) { - dst[0] = (unsigned char)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp); - dst[1] = (unsigned char)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp); - dst[2] = (unsigned char)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp); - dst[3] = (unsigned char)divide_round_i(tmp, 255); + dst[0] = (uchar)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp); + dst[1] = (uchar)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp); + dst[2] = (uchar)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp); + dst[3] = (uchar)divide_round_i(tmp, 255); } else { copy_v4_v4_uchar(dst, src1); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index a17fecca303..e0e463615e5 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4152,33 +4152,36 @@ struct Float2_Len { static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, const struct Float3_Len *d_next) { - float cross[3], area; + float cross[3]; cross_v3_v3v3(cross, d_curr->dir, d_next->dir); - area = len_v3(cross); - if (LIKELY(fabsf(area) > FLT_EPSILON)) { + const float area = len_v3(cross); + /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */ + if (LIKELY(area != 0.0f)) { const float dot = dot_v3v3(d_curr->dir, d_next->dir); const float len = d_curr->len * d_next->len; - return (len - dot) / area; - } - else { - return 0.0f; + const float result = (len - dot) / area; + if (isfinite(result)) { + return result; + } } + return 0.0f; } static float mean_value_half_tan_v2(const struct Float2_Len *d_curr, const struct Float2_Len *d_next) { - float area; /* different from the 3d version but still correct */ - area = cross_v2v2(d_curr->dir, d_next->dir); - if (LIKELY(fabsf(area) > FLT_EPSILON)) { + const float area = cross_v2v2(d_curr->dir, d_next->dir); + /* Compare against zero since 'FLT_EPSILON' can be too large, see: T73348. */ + if (LIKELY(area != 0.0f)) { const float dot = dot_v2v2(d_curr->dir, d_next->dir); const float len = d_curr->len * d_next->len; - return (len - dot) / area; - } - else { - return 0.0f; + const float result = (len - dot) / area; + if (isfinite(result)) { + return result; + } } + return 0.0f; } void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3]) diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 55f21250659..5919b7e1dd6 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -240,10 +240,7 @@ void interp_v3_v3v3v3_uv( p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]); } -void interp_v3_v3v3_uchar(char unsigned target[3], - const unsigned char a[3], - const unsigned char b[3], - const float t) +void interp_v3_v3v3_uchar(uchar target[3], const uchar a[3], const uchar b[3], const float t) { const float s = 1.0f - t; @@ -253,14 +250,10 @@ void interp_v3_v3v3_uchar(char unsigned target[3], } void interp_v3_v3v3_char(char target[3], const char a[3], const char b[3], const float t) { - interp_v3_v3v3_uchar( - (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t); + interp_v3_v3v3_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t); } -void interp_v4_v4v4_uchar(char unsigned target[4], - const unsigned char a[4], - const unsigned char b[4], - const float t) +void interp_v4_v4v4_uchar(uchar target[4], const uchar a[4], const uchar b[4], const float t) { const float s = 1.0f - t; @@ -271,8 +264,7 @@ void interp_v4_v4v4_uchar(char unsigned target[4], } void interp_v4_v4v4_char(char target[4], const char a[4], const char b[4], const float t) { - interp_v4_v4v4_uchar( - (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t); + interp_v4_v4v4_uchar((uchar *)target, (const uchar *)a, (const uchar *)b, t); } void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3]) @@ -303,12 +295,12 @@ void mid_v3_v3v3v3v3( v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f; } -void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr) +void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr) { const float factor = 1.0f / (float)nbr; zero_v3(r); - for (unsigned int i = 0; i < nbr; i++) { + for (uint i = 0; i < nbr; i++) { madd_v3_v3fl(r, vec_arr[i], factor); } } @@ -1119,10 +1111,10 @@ void range_vn_i(int *array_tar, const int size, const int start) } } -void range_vn_u(unsigned int *array_tar, const int size, const unsigned int start) +void range_vn_u(uint *array_tar, const int size, const uint start) { - unsigned int *array_pt = array_tar + (size - 1); - unsigned int j = start + (unsigned int)(size - 1); + uint *array_pt = array_tar + (size - 1); + uint j = start + (uint)(size - 1); int i = size; while (i--) { *(array_pt--) = j--; @@ -1329,18 +1321,18 @@ void copy_vn_short(short *array_tar, const int size, const short val) } } -void copy_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val) +void copy_vn_ushort(ushort *array_tar, const int size, const ushort val) { - unsigned short *tar = array_tar + (size - 1); + ushort *tar = array_tar + (size - 1); int i = size; while (i--) { *(tar--) = val; } } -void copy_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val) +void copy_vn_uchar(uchar *array_tar, const int size, const uchar val) { - unsigned char *tar = array_tar + (size - 1); + uchar *tar = array_tar + (size - 1); int i = size; while (i--) { *(tar--) = val; diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 63657f33bba..7fc95a33092 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -600,7 +600,7 @@ uint BLI_str_utf8_as_unicode(const char *p) uint BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index) { int i, len; - unsigned mask = 0; + uint mask = 0; uint result; const unsigned char c = (unsigned char)*p; diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c index b956e1c0a7e..85cb32b6457 100644 --- a/source/blender/blenlib/intern/string_utils.c +++ b/source/blender/blenlib/intern/string_utils.c @@ -410,12 +410,30 @@ bool BLI_uniquename( /** \name Join Strings * * For non array versions of these functions, use the macros: + * - #BLI_string_join * - #BLI_string_joinN * - #BLI_string_join_by_sep_charN * - #BLI_string_join_by_sep_char_with_tableN * * \{ */ +char *BLI_string_join_array(char *result, + size_t result_len, + const char *strings[], + uint strings_len) +{ + char *c = result; + char *c_end = &result[result_len - 1]; + for (uint i = 0; i < strings_len; i++) { + const char *p = strings[i]; + while (*p && (c < c_end)) { + *c++ = *p++; + } + } + *c = '\0'; + return c; +} + /** * Join an array of strings into a newly allocated, null terminated string. */ |