upgrade Filament to v1.41

This commit is contained in:
Nick Fisher
2023-08-18 12:01:14 +08:00
parent e62bf64c04
commit d82bdff939
72 changed files with 2455 additions and 2514 deletions

View File

@@ -41,11 +41,13 @@ class StructureOfArraysBase {
static constexpr const size_t kArrayCount = sizeof...(Elements);
public:
using SoA = StructureOfArraysBase<Allocator, Elements ...>;
using SoA = StructureOfArraysBase<Allocator, Elements...>;
using Structure = std::tuple<Elements...>;
// Type of the Nth array
template<size_t N>
using TypeAt = typename std::tuple_element_t<N, std::tuple<Elements...>>;
using TypeAt = typename std::tuple_element_t<N, Structure>;
// Number of arrays
static constexpr size_t getArrayCount() noexcept { return kArrayCount; }
@@ -57,7 +59,7 @@ public:
// --------------------------------------------------------------------------------------------
class Structure;
class IteratorValue;
template<typename T> class Iterator;
using iterator = Iterator<StructureOfArraysBase*>;
using const_iterator = Iterator<StructureOfArraysBase const*>;
@@ -69,45 +71,45 @@ public:
* In other words, it's the return type of iterator::operator*(), and since it
* cannot be a C++ reference (&), it's an object that acts like it.
*/
class StructureRef {
friend class Structure;
class IteratorValueRef {
friend class IteratorValue;
friend iterator;
friend const_iterator;
StructureOfArraysBase* const UTILS_RESTRICT soa;
size_t const index;
StructureRef(StructureOfArraysBase* soa, size_t index) : soa(soa), index(index) { }
IteratorValueRef(StructureOfArraysBase* soa, size_t index) : soa(soa), index(index) { }
// assigns a value_type to a reference (i.e. assigns to what's pointed to by the reference)
template<size_t ... Is>
StructureRef& assign(Structure const& rhs, std::index_sequence<Is...>);
IteratorValueRef& assign(IteratorValue const& rhs, std::index_sequence<Is...>);
// assigns a value_type to a reference (i.e. assigns to what's pointed to by the reference)
template<size_t ... Is>
StructureRef& assign(Structure&& rhs, std::index_sequence<Is...>) noexcept;
IteratorValueRef& assign(IteratorValue&& rhs, std::index_sequence<Is...>) noexcept;
// objects pointed to by reference can be swapped, so provide the special swap() function.
friend void swap(StructureRef lhs, StructureRef rhs) {
friend void swap(IteratorValueRef lhs, IteratorValueRef rhs) {
lhs.soa->swap(lhs.index, rhs.index);
}
public:
// references can be created by copy-assignment only
StructureRef(StructureRef const& rhs) noexcept : soa(rhs.soa), index(rhs.index) { }
IteratorValueRef(IteratorValueRef const& rhs) noexcept : soa(rhs.soa), index(rhs.index) { }
// copy the content of a reference to the content of this one
StructureRef& operator=(StructureRef const& rhs);
IteratorValueRef& operator=(IteratorValueRef const& rhs);
// move the content of a reference to the content of this one
StructureRef& operator=(StructureRef&& rhs) noexcept;
IteratorValueRef& operator=(IteratorValueRef&& rhs) noexcept;
// copy a value_type to the content of this reference
StructureRef& operator=(Structure const& rhs) {
IteratorValueRef& operator=(IteratorValue const& rhs) {
return assign(rhs, std::make_index_sequence<kArrayCount>());
}
// move a value_type to the content of this reference
StructureRef& operator=(Structure&& rhs) noexcept {
IteratorValueRef& operator=(IteratorValue&& rhs) noexcept {
return assign(rhs, std::make_index_sequence<kArrayCount>());
}
@@ -122,36 +124,36 @@ public:
* Internally we're using a tuple<> to store the data.
* This object is not trivial to construct, as it copies an entry of the SoA.
*/
class Structure {
friend class StructureRef;
class IteratorValue {
friend class IteratorValueRef;
friend iterator;
friend const_iterator;
using Type = std::tuple<typename std::decay<Elements>::type...>;
Type elements;
template<size_t ... Is>
static Type init(StructureRef const& rhs, std::index_sequence<Is...>) {
static Type init(IteratorValueRef const& rhs, std::index_sequence<Is...>) {
return Type{ rhs.soa->template elementAt<Is>(rhs.index)... };
}
template<size_t ... Is>
static Type init(StructureRef&& rhs, std::index_sequence<Is...>) noexcept {
static Type init(IteratorValueRef&& rhs, std::index_sequence<Is...>) noexcept {
return Type{ std::move(rhs.soa->template elementAt<Is>(rhs.index))... };
}
public:
Structure(Structure const& rhs) = default;
Structure(Structure&& rhs) noexcept = default;
Structure& operator=(Structure const& rhs) = default;
Structure& operator=(Structure&& rhs) noexcept = default;
IteratorValue(IteratorValue const& rhs) = default;
IteratorValue(IteratorValue&& rhs) noexcept = default;
IteratorValue& operator=(IteratorValue const& rhs) = default;
IteratorValue& operator=(IteratorValue&& rhs) noexcept = default;
// initialize and assign from a StructureRef
Structure(StructureRef const& rhs)
IteratorValue(IteratorValueRef const& rhs)
: elements(init(rhs, std::make_index_sequence<kArrayCount>())) {}
Structure(StructureRef&& rhs) noexcept
IteratorValue(IteratorValueRef&& rhs) noexcept
: elements(init(rhs, std::make_index_sequence<kArrayCount>())) {}
Structure& operator=(StructureRef const& rhs) { return operator=(Structure(rhs)); }
Structure& operator=(StructureRef&& rhs) noexcept { return operator=(Structure(rhs)); }
IteratorValue& operator=(IteratorValueRef const& rhs) { return operator=(IteratorValue(rhs)); }
IteratorValue& operator=(IteratorValueRef&& rhs) noexcept { return operator=(IteratorValue(rhs)); }
// access the elements of this value_Type (i.e. the "fields" of the structure)
template<size_t I> TypeAt<I> const& get() const { return std::get<I>(elements); }
@@ -174,9 +176,9 @@ public:
Iterator(CVQualifiedSOAPointer soa, size_t index) : soa(soa), index(index) {}
public:
using value_type = Structure;
using reference = StructureRef;
using pointer = StructureRef*; // FIXME: this should be a StructurePtr type
using value_type = IteratorValue;
using reference = IteratorValueRef;
using pointer = IteratorValueRef*; // FIXME: this should be a StructurePtr type
using difference_type = ptrdiff_t;
using iterator_category = std::random_access_iterator_tag;
@@ -335,6 +337,11 @@ public:
return *this;
}
StructureOfArraysBase& push_back(Structure&& args) noexcept {
ensureCapacity(mSize + 1);
return push_back_unsafe(std::forward<Structure>(args));
}
StructureOfArraysBase& push_back(Elements const& ... args) noexcept {
ensureCapacity(mSize + 1);
return push_back_unsafe(args...);
@@ -349,23 +356,29 @@ public:
struct PushBackUnsafeClosure {
size_t last;
std::tuple<Elements...> args;
inline explicit PushBackUnsafeClosure(size_t last, Elements&& ... args)
: last(last), args(std::forward<Elements>(args)...) {}
inline explicit PushBackUnsafeClosure(size_t last, Elements const& ... args)
: last(last), args(args...) {}
inline explicit PushBackUnsafeClosure(size_t last, Structure&& args)
: last(last), args(std::forward<Structure>(args)) {}
template<size_t I>
inline void operator()(TypeAt<I>* p) {
new(p + last) TypeAt<I>{ std::get<I>(args) };
}
};
StructureOfArraysBase& push_back_unsafe(Structure&& args) noexcept {
for_each_index(mArrays,
PushBackUnsafeClosure{ mSize++, std::forward<Structure>(args) });
return *this;
}
StructureOfArraysBase& push_back_unsafe(Elements const& ... args) noexcept {
for_each_index(mArrays, PushBackUnsafeClosure{ mSize++, args... });
for_each_index(mArrays,
PushBackUnsafeClosure{ mSize++, { args... } });
return *this;
}
StructureOfArraysBase& push_back_unsafe(Elements&& ... args) noexcept {
for_each_index(mArrays, PushBackUnsafeClosure{ mSize++, std::forward<Elements>(args)... });
for_each_index(mArrays,
PushBackUnsafeClosure{ mSize++, { std::forward<Elements>(args)... }});
return *this;
}
@@ -562,8 +575,10 @@ private:
forEach([from, to](auto p) {
using T = typename std::decay<decltype(*p)>::type;
// note: scalar types like int/float get initialized to zero
for (size_t i = from; i < to; i++) {
new(p + i) T();
if constexpr (!std::is_trivially_default_constructible_v<T>) {
for (size_t i = from; i < to; i++) {
new(p + i) T();
}
}
});
}
@@ -571,8 +586,10 @@ private:
void destroy_each(size_t from, size_t to) noexcept {
forEach([from, to](auto p) {
using T = typename std::decay<decltype(*p)>::type;
for (size_t i = from; i < to; i++) {
p[i].~T();
if constexpr (!std::is_trivially_destructible_v<T>) {
for (size_t i = from; i < to; i++) {
p[i].~T();
}
}
});
}
@@ -592,15 +609,17 @@ private:
reinterpret_cast<T*>(uintptr_t(b) + offsets[index]);
// for trivial cases, just call memcpy()
if (std::is_trivially_copyable<T>::value &&
std::is_trivially_destructible<T>::value) {
if constexpr (std::is_trivially_copyable_v<T> &&
std::is_trivially_destructible_v<T>) {
memcpy(arrayPointer, p, size * sizeof(T));
} else {
for (size_t i = 0; i < size; i++) {
// we move an element by using the in-place move-constructor
new(arrayPointer + i) T(std::move(p[i]));
// and delete them by calling the destructor directly
p[i].~T();
if constexpr (!std::is_trivially_destructible_v<T>) {
// and delete them by calling the destructor directly
p[i].~T();
}
}
}
index++;
@@ -626,27 +645,27 @@ private:
template<typename Allocator, typename... Elements>
inline
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
StructureOfArraysBase<Allocator, Elements...>::StructureRef::operator=(
StructureOfArraysBase::StructureRef const& rhs) {
return operator=(Structure(rhs));
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::operator=(
StructureOfArraysBase::IteratorValueRef const& rhs) {
return operator=(IteratorValue(rhs));
}
template<typename Allocator, typename... Elements>
inline
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
StructureOfArraysBase<Allocator, Elements...>::StructureRef::operator=(
StructureOfArraysBase::StructureRef&& rhs) noexcept {
return operator=(Structure(rhs));
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::operator=(
StructureOfArraysBase::IteratorValueRef&& rhs) noexcept {
return operator=(IteratorValue(rhs));
}
template<typename Allocator, typename... Elements>
template<size_t... Is>
inline
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
StructureOfArraysBase::Structure const& rhs, std::index_sequence<Is...>) {
// implements StructureRef& StructureRef::operator=(Structure const& rhs)
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
StructureOfArraysBase::IteratorValue const& rhs, std::index_sequence<Is...>) {
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue const& rhs)
auto UTILS_UNUSED l = { (soa->elementAt<Is>(index) = std::get<Is>(rhs.elements), 0)... };
return *this;
}
@@ -654,10 +673,10 @@ StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
template<typename Allocator, typename... Elements>
template<size_t... Is>
inline
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
StructureOfArraysBase::Structure&& rhs, std::index_sequence<Is...>) noexcept {
// implements StructureRef& StructureRef::operator=(Structure&& rhs) noexcept
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
StructureOfArraysBase::IteratorValue&& rhs, std::index_sequence<Is...>) noexcept {
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue&& rhs) noexcept
auto UTILS_UNUSED l = {
(soa->elementAt<Is>(index) = std::move(std::get<Is>(rhs.elements)), 0)... };
return *this;