[LYN-6838] Various Monolithic shutdown fixes for the GameLauncher (#4564)
* Added a stateless allocator which uses AZ_OS_MALLOC/AZ_OS_FREE to allocate memory for objects in static memory. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the Maestro and LyShine Anim Nodes to use the stateless_allocator for its static containers. This prevents crashes in static de-init due to the SystemAllocator being destroyed at that poitn Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the EBus AllocatorType to use the EBusEnvironmentAllocator Because the EBus Context resides in static memory, the SystemAllocator lifetime is shorter than the EBus Context. This results in shutdown crashes in monolithic builds due to all of the gem modules being linked in as static libraries and the EBus context now destructing at the point of the executable static de-init, instead of the module de-init, where the SystemAllocator would still be around. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed an assortment of shutdown issues due to deleting objects after AZ allocators are no longer available Fixed the NameDictionary IsReady() function to not assert when the dictionary when invoked after the environment variable it was stored in was destroyed. Updated the NameData destructor to check that the NameDictionary IsReady() before attempting to remove itself from the dictionary Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed NameDictionary destory workflow, to reset the EnvironmentVariable instance Updated the EnvironmentVariable instance to store the NameDictionary as a value. Added a rvalue reference `Set` function overload to the EnvironmentVariable class to support move only types. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Clang 6.0.0 build fixes The C++17 std::launder feature isn't available in that compiler version Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
3af07e5117
commit
97e9f4dc7d
@@ -77,9 +77,11 @@ namespace AZ
|
||||
public:
|
||||
/**
|
||||
* Allocator used by the EBus.
|
||||
* The default setting is AZStd::allocator, which uses AZ::SystemAllocator.
|
||||
* The default setting is Internal EBusEnvironmentAllocator
|
||||
* EBus code stores their Context instances in static memory
|
||||
* Therfore the configured allocator must last as long as the EBus in a module
|
||||
*/
|
||||
using AllocatorType = AZStd::allocator;
|
||||
using AllocatorType = AZ::Internal::EBusEnvironmentAllocator;
|
||||
|
||||
/**
|
||||
* Defines how many handlers can connect to an address on the EBus
|
||||
|
||||
@@ -34,7 +34,9 @@ namespace AZ
|
||||
friend IAllocator;
|
||||
friend class AllocatorBase;
|
||||
friend class Debug::AllocationRecords;
|
||||
friend class AZ::Internal::EnvironmentVariableHolder<AllocatorManager>;
|
||||
template<typename T, typename... Args> friend constexpr auto AZStd::construct_at(T*, Args&&... args)
|
||||
->AZStd::enable_if_t<AZStd::is_void_v<AZStd::void_t<decltype(new (AZStd::declval<void*>()) T(AZStd::forward<Args>(args)...))>>, T*>;
|
||||
template<typename T> constexpr friend void AZStd::destroy_at(T*);
|
||||
|
||||
public:
|
||||
typedef AZStd::function<void (IAllocator* allocator, size_t /*byteSize*/, size_t /*alignment*/, int/* flags*/, const char* /*name*/, const char* /*fileName*/, int lineNum /*=0*/)> OutOfMemoryCBType;
|
||||
|
||||
@@ -251,16 +251,15 @@ namespace AZ
|
||||
class EnvironmentVariableHolder
|
||||
: public EnvironmentVariableHolderBase
|
||||
{
|
||||
void ConstructImpl(const AZStd::true_type& /* AZStd::has_trivial_constructor<T> */)
|
||||
{
|
||||
memset(&m_value, 0, sizeof(T));
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
void ConstructImpl(const AZStd::false_type& /* AZStd::has_trivial_constructor<T> */, Args&&... args)
|
||||
void ConstructImpl(Args&&... args)
|
||||
{
|
||||
// Construction of non-trivial types is left up to the type's constructor.
|
||||
new(&m_value) T(AZStd::forward<Args>(args)...);
|
||||
// Use std::launder to ensure that the compiler treats the T* reinterpret_cast as a new object
|
||||
#if __cpp_lib_launder
|
||||
AZStd::construct_at(std::launder(reinterpret_cast<T*>(&m_value)), AZStd::forward<Args>(args)...);
|
||||
#else
|
||||
AZStd::construct_at(reinterpret_cast<T*>(&m_value), AZStd::forward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
static void DestructDispatchNoLock(EnvironmentVariableHolderBase *base, DestroyTarget selfDestruct)
|
||||
{
|
||||
@@ -274,10 +273,12 @@ namespace AZ
|
||||
AZ_Assert(self->m_isConstructed, "Variable is not constructed. Please check your logic and guard if needed!");
|
||||
self->m_isConstructed = false;
|
||||
self->m_moduleOwner = nullptr;
|
||||
if constexpr(!AZStd::is_trivially_destructible_v<T>)
|
||||
{
|
||||
reinterpret_cast<T*>(&self->m_value)->~T();
|
||||
}
|
||||
// Use std::launder to ensure that the compiler treats the T* reinterpret_cast as a new object
|
||||
#if __cpp_lib_launder
|
||||
AZStd::destroy_at(std::launder(reinterpret_cast<T*>(&self->m_value)));
|
||||
#else
|
||||
AZStd::destroy_at(reinterpret_cast<T*>(&self->m_value));
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
EnvironmentVariableHolder(u32 guid, bool isOwnershipTransfer, Environment::AllocatorInterface* allocator)
|
||||
@@ -303,24 +304,13 @@ namespace AZ
|
||||
UnregisterAndDestroy(DestructDispatchNoLock, moduleRelease);
|
||||
}
|
||||
|
||||
void Construct()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::spin_mutex> lock(m_mutex);
|
||||
if (!m_isConstructed)
|
||||
{
|
||||
ConstructImpl(AZStd::is_trivially_constructible<T>{});
|
||||
m_isConstructed = true;
|
||||
m_moduleOwner = Environment::GetModuleId();
|
||||
}
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void Construct(Args&&... args)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::spin_mutex> lock(m_mutex);
|
||||
if (!m_isConstructed)
|
||||
{
|
||||
ConstructImpl(typename AZStd::false_type(), AZStd::forward<Args>(args)...);
|
||||
ConstructImpl(AZStd::forward<Args>(args)...);
|
||||
m_isConstructed = true;
|
||||
m_moduleOwner = Environment::GetModuleId();
|
||||
}
|
||||
@@ -333,7 +323,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
// variable storage
|
||||
typename AZStd::aligned_storage<sizeof(T), AZStd::alignment_of<T>::value>::type m_value;
|
||||
AZStd::aligned_storage_for_t<T> m_value;
|
||||
static int s_moduleUseCount;
|
||||
};
|
||||
|
||||
@@ -468,6 +458,11 @@ namespace AZ
|
||||
Get() = value;
|
||||
}
|
||||
|
||||
void Set(T&& value)
|
||||
{
|
||||
Get() = AZStd::move(value);
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return IsValid();
|
||||
|
||||
@@ -42,7 +42,10 @@ namespace AZ
|
||||
AZ_Assert(m_useCount > 0, "m_useCount is already 0!");
|
||||
if (m_useCount.fetch_sub(1) == 1)
|
||||
{
|
||||
AZ::NameDictionary::Instance().TryReleaseName(hash);
|
||||
if (AZ::NameDictionary::IsReady())
|
||||
{
|
||||
AZ::NameDictionary::Instance().TryReleaseName(hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,23 +21,18 @@ namespace AZ
|
||||
|
||||
namespace NameDictionaryInternal
|
||||
{
|
||||
static AZ::EnvironmentVariable<NameDictionary*> s_instance = nullptr;
|
||||
static AZ::EnvironmentVariable<NameDictionary> s_instance = nullptr;
|
||||
}
|
||||
|
||||
void NameDictionary::Create()
|
||||
{
|
||||
using namespace NameDictionaryInternal;
|
||||
|
||||
AZ_Assert(!s_instance || !s_instance.Get(), "NameDictionary already created!");
|
||||
AZ_Assert(!s_instance, "NameDictionary already created!");
|
||||
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = AZ::Environment::CreateVariable<NameDictionary*>(NameDictionaryInstanceName);
|
||||
}
|
||||
|
||||
if (!s_instance.Get())
|
||||
{
|
||||
s_instance.Set(aznew NameDictionary());
|
||||
s_instance = AZ::Environment::CreateVariable<NameDictionary>(NameDictionaryInstanceName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +41,7 @@ namespace AZ
|
||||
using namespace NameDictionaryInternal;
|
||||
|
||||
AZ_Assert(s_instance, "NameDictionary not created!");
|
||||
delete (*s_instance);
|
||||
*s_instance = nullptr;
|
||||
s_instance.Reset();
|
||||
}
|
||||
|
||||
bool NameDictionary::IsReady()
|
||||
@@ -56,10 +50,10 @@ namespace AZ
|
||||
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = Environment::FindVariable<NameDictionary*>(NameDictionaryInstanceName);
|
||||
s_instance = Environment::FindVariable<NameDictionary>(NameDictionaryInstanceName);
|
||||
}
|
||||
|
||||
return s_instance && *s_instance;
|
||||
return s_instance.IsConstructed();
|
||||
}
|
||||
|
||||
NameDictionary& NameDictionary::Instance()
|
||||
@@ -68,12 +62,12 @@ namespace AZ
|
||||
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = Environment::FindVariable<NameDictionary*>(NameDictionaryInstanceName);
|
||||
s_instance = Environment::FindVariable<NameDictionary>(NameDictionaryInstanceName);
|
||||
}
|
||||
|
||||
AZ_Assert(s_instance && *s_instance, "NameDictionary has not been initialized yet.");
|
||||
AZ_Assert(s_instance.IsConstructed(), "NameDictionary has not been initialized yet.");
|
||||
|
||||
return *(*s_instance);
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
NameDictionary::NameDictionary()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
|
||||
namespace MaterialEditor
|
||||
namespace MaterialEditor
|
||||
{
|
||||
class MaterialEditorCoreComponent;
|
||||
}
|
||||
@@ -34,14 +34,14 @@ namespace AZ
|
||||
{
|
||||
class NameData;
|
||||
};
|
||||
|
||||
|
||||
//! Maintains a list of unique strings for Name objects.
|
||||
//! The main benefit of the Name system is very fast string equality comparison, because every
|
||||
//! unique name has a unique ID. The NameDictionary's purpose is to guarantee name IDs do not
|
||||
//! unique name has a unique ID. The NameDictionary's purpose is to guarantee name IDs do not
|
||||
//! collide. It also saves memory by removing duplicate strings.
|
||||
//!
|
||||
//! Benchmarks have shown that creating a new Name object can be quite slow when the name doesn't
|
||||
//! already exist in the NameDictionary, but is comparable to creating an AZStd::string for names
|
||||
//! Benchmarks have shown that creating a new Name object can be quite slow when the name doesn't
|
||||
//! already exist in the NameDictionary, but is comparable to creating an AZStd::string for names
|
||||
//! that already exist.
|
||||
class NameDictionary final
|
||||
{
|
||||
@@ -51,7 +51,10 @@ namespace AZ
|
||||
friend Name;
|
||||
friend Internal::NameData;
|
||||
friend UnitTest::NameDictionaryTester;
|
||||
|
||||
template<typename T, typename... Args> friend constexpr auto AZStd::construct_at(T*, Args&&... args)
|
||||
-> AZStd::enable_if_t<AZStd::is_void_v<AZStd::void_t<decltype(new (AZStd::declval<void*>()) T(AZStd::forward<Args>(args)...))>>, T*>;
|
||||
template<typename T> constexpr friend void AZStd::destroy_at(T*);
|
||||
|
||||
public:
|
||||
|
||||
static void Create();
|
||||
@@ -62,7 +65,7 @@ namespace AZ
|
||||
|
||||
//! Makes a Name from the provided raw string. If an entry already exists in the dictionary, it is shared.
|
||||
//! Otherwise, it is added to the internal dictionary.
|
||||
//!
|
||||
//!
|
||||
//! @param name The name to resolve against the dictionary.
|
||||
//! @return A Name instance holding a dictionary entry associated with the provided raw string.
|
||||
Name MakeName(AZStd::string_view name);
|
||||
@@ -84,13 +87,13 @@ namespace AZ
|
||||
// Attempts to release the name from the dictionary, but checks to make sure
|
||||
// a reference wasn't taken by another thread.
|
||||
void TryReleaseName(Name::Hash hash);
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Calculates a hash for the provided name string.
|
||||
// Does not attempt to resolve hash collisions; that is handled elsewhere.
|
||||
Name::Hash CalcHash(AZStd::string_view name);
|
||||
|
||||
|
||||
AZStd::unordered_map<Name::Hash, Internal::NameData*> m_dictionary;
|
||||
mutable AZStd::shared_mutex m_sharedMutex;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
stateless_allocator::stateless_allocator(const char* name)
|
||||
: m_name(name) {}
|
||||
|
||||
const char* stateless_allocator::get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void stateless_allocator::set_name(const char* name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
auto stateless_allocator::allocate(size_type byteSize) -> pointer_type
|
||||
{
|
||||
return allocate(byteSize, AZ_DEFAULT_ALIGNMENT, 0);
|
||||
}
|
||||
|
||||
auto stateless_allocator::allocate(size_type byteSize, size_type alignment, int) -> pointer_type
|
||||
{
|
||||
pointer_type address = AZ_OS_MALLOC(byteSize, alignment);
|
||||
|
||||
if (address == nullptr)
|
||||
{
|
||||
AZ_Error("Memory", false, "stateless_allocator ran out of system memory!\n");
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void stateless_allocator::deallocate(pointer_type ptr, size_type)
|
||||
{
|
||||
AZ_OS_FREE(ptr);
|
||||
}
|
||||
|
||||
void stateless_allocator::deallocate(pointer_type ptr, size_type, size_type)
|
||||
{
|
||||
AZ_OS_FREE(ptr);
|
||||
}
|
||||
|
||||
auto stateless_allocator::max_size() const -> size_type
|
||||
{
|
||||
return AZ_CORE_MAX_ALLOCATOR_SIZE;
|
||||
}
|
||||
|
||||
stateless_allocator stateless_allocator::select_on_container_copy_construction() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto stateless_allocator::resize(pointer_type, size_type) -> size_type
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool stateless_allocator::is_lock_free()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool stateless_allocator::is_stale_read_allowed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool stateless_allocator::is_delayed_recycling()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// comparison operators
|
||||
bool operator==(const stateless_allocator&, const stateless_allocator&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const stateless_allocator&, const stateless_allocator&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/base.h>
|
||||
#include <AzCore/std/typetraits/integral_constant.h>
|
||||
#include <AzCore/RTTI/TypeInfoSimple.h>
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
class stateless_allocator
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_TYPE_INFO(stateless_allocator, "{E4976C53-0B20-4F39-8D41-0A76F59A7D68}");
|
||||
|
||||
using value_type = uint8_t;
|
||||
using pointer_type = void*;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using allow_memory_leaks = AZStd::true_type;
|
||||
|
||||
stateless_allocator(const char* name = "AZStd::stateless_allocator");
|
||||
stateless_allocator(const stateless_allocator& rhs) = default;
|
||||
|
||||
stateless_allocator& operator=(const stateless_allocator& rhs) = default;
|
||||
|
||||
const char* get_name() const;
|
||||
void set_name(const char* name);
|
||||
|
||||
pointer_type allocate(size_type byteSize);
|
||||
pointer_type allocate(size_type byteSize, size_type alignment, int flags = 0);
|
||||
void deallocate(pointer_type ptr, size_type alignment);
|
||||
void deallocate(pointer_type ptr, size_type byteSize, size_type alignment);
|
||||
|
||||
// max_size actually returns the true maximum size of a single allocation
|
||||
size_type max_size() const;
|
||||
|
||||
// Returns a copy of the allocator
|
||||
stateless_allocator select_on_container_copy_construction() const;
|
||||
|
||||
//! extensions
|
||||
size_type resize(pointer_type ptr, size_type newSize);
|
||||
|
||||
bool is_lock_free();
|
||||
bool is_stale_read_allowed();
|
||||
bool is_delayed_recycling();
|
||||
|
||||
private:
|
||||
const char* m_name;
|
||||
};
|
||||
|
||||
bool operator==(const stateless_allocator& left, const stateless_allocator& right);
|
||||
bool operator!=(const stateless_allocator& left, const stateless_allocator& right);
|
||||
}
|
||||
@@ -12,6 +12,8 @@ set(FILES
|
||||
allocator.h
|
||||
allocator_ref.h
|
||||
allocator_stack.h
|
||||
allocator_stateless.cpp
|
||||
allocator_stateless.h
|
||||
allocator_static.h
|
||||
allocator_traits.h
|
||||
any.h
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
// alias std::pointer_traits into the AZStd::namespace
|
||||
// alias std::pointer_traits into the AZStd::namespace
|
||||
using std::pointer_traits;
|
||||
|
||||
//! Bring the names of uninitialized_default_construct and
|
||||
@@ -229,7 +229,7 @@ namespace AZStd
|
||||
//! `new (declval<void*>()) T(declval<Args>()...)` is well-formed
|
||||
template <typename T, typename... Args>
|
||||
constexpr auto construct_at(T* ptr, Args&&... args)
|
||||
-> enable_if_t<is_void_v<void_t<decltype(new (declval<void*>()) T(AZStd::forward<Args>(args)...))>>, T*>
|
||||
-> enable_if_t<AZStd::is_void_v<AZStd::void_t<decltype(new (AZStd::declval<void*>()) T(AZStd::forward<Args>(args)...))>>, T*>
|
||||
{
|
||||
return ::new (ptr) T(AZStd::forward<Args>(args)...);
|
||||
}
|
||||
@@ -487,7 +487,7 @@ namespace AZStd
|
||||
{
|
||||
//! Implements the C++17 uninitialized_move function
|
||||
//! The functions accepts two input iterators and an output iterator
|
||||
//! It performs an AZStd::move on each in in the range of the input iterator
|
||||
//! It performs an AZStd::move on each in in the range of the input iterator
|
||||
//! and stores the result in location pointed by the output iterator
|
||||
template <typename InputIt, typename ForwardIt>
|
||||
ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt result)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
|
||||
#include <Range.h>
|
||||
#include <AnimKey.h>
|
||||
@@ -181,7 +182,7 @@ public:
|
||||
|
||||
private:
|
||||
AnimParamType m_type;
|
||||
AZStd::string m_name;
|
||||
AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator> m_name;
|
||||
};
|
||||
|
||||
namespace AZStd
|
||||
@@ -617,7 +618,7 @@ public:
|
||||
, valueType(_valueType)
|
||||
, flags(_flags) {};
|
||||
|
||||
AZStd::string name; // parameter name.
|
||||
AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator> name; // parameter name.
|
||||
CAnimParamType paramType; // parameter id.
|
||||
AnimValueType valueType; // value type, defines type of track to use for animating this parameter.
|
||||
ESupportedParamFlags flags; // combination of flags from ESupportedParamFlags.
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
@@ -491,6 +492,13 @@ namespace stl
|
||||
return type;
|
||||
}
|
||||
|
||||
//! Specialization of string to const char cast.
|
||||
template <>
|
||||
inline const char* constchar_cast(const AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator>& type)
|
||||
{
|
||||
return type.c_str();
|
||||
}
|
||||
|
||||
//! Specialization of string to const char cast.
|
||||
template <>
|
||||
inline const char* constchar_cast(const AZStd::string& type)
|
||||
|
||||
@@ -357,7 +357,7 @@ namespace AZ
|
||||
// Texture2DArray<float2> m_decalTextureArrayNormalMaps0;
|
||||
// Texture2DArray<float2> m_decalTextureArrayNormalMaps1;
|
||||
// Texture2DArray<float2> m_decalTextureArrayNormalMaps2;
|
||||
static const AZStd::array<AZStd::string, DecalMapType_Num> ShaderNames = { "m_decalTextureArrayDiffuse",
|
||||
static constexpr AZStd::array<AZStd::string_view, DecalMapType_Num> ShaderNames = { "m_decalTextureArrayDiffuse",
|
||||
"m_decalTextureArrayNormalMaps" };
|
||||
|
||||
for (int mapType = 0; mapType < DecalMapType_Num; ++mapType)
|
||||
@@ -365,7 +365,7 @@ namespace AZ
|
||||
for (int texArrayIdx = 0; texArrayIdx < NumTextureArrays; ++texArrayIdx)
|
||||
{
|
||||
const RHI::ShaderResourceGroupLayout* viewSrgLayout = RPI::RPISystemInterface::Get()->GetViewSrgLayout().get();
|
||||
const AZStd::string baseName = ShaderNames[mapType] + AZStd::to_string(texArrayIdx);
|
||||
const AZStd::string baseName = AZStd::string(ShaderNames[mapType]) + AZStd::to_string(texArrayIdx);
|
||||
|
||||
m_decalTextureArrayIndices[texArrayIdx][mapType] = viewSrgLayout->FindShaderInputImageIndex(Name(baseName.c_str()));
|
||||
AZ_Warning(
|
||||
|
||||
@@ -346,7 +346,7 @@ namespace AZ::Render
|
||||
|
||||
void ProjectedShadowFeatureProcessor::CacheEsmShadowmapsPass(const AZStd::vector<RPI::RenderPipelineId>& validPipelineIds)
|
||||
{
|
||||
static const Name LightTypeName = Name("projected");
|
||||
const Name LightTypeName = Name("projected");
|
||||
|
||||
const auto* passSystem = RPI::PassSystemInterface::Get();
|
||||
const AZStd::vector<RPI::Pass*> passes = passSystem->GetPassesForTemplateName(Name("EsmShadowmapsTemplate"));
|
||||
|
||||
@@ -16,12 +16,27 @@ namespace AZ
|
||||
{
|
||||
static const uint32_t s_minVulkanSupportedVersion = VK_API_VERSION_1_0;
|
||||
|
||||
static EnvironmentVariable<Instance> s_vulkanInstance;
|
||||
static constexpr const char* s_vulkanInstanceKey = "VulkanInstance";
|
||||
|
||||
Instance& Instance::GetInstance()
|
||||
{
|
||||
static Instance s_instance;
|
||||
return s_instance;
|
||||
if (!s_vulkanInstance)
|
||||
{
|
||||
s_vulkanInstance = Environment::FindVariable<Instance>(s_vulkanInstanceKey);
|
||||
if (!s_vulkanInstance)
|
||||
{
|
||||
s_vulkanInstance = Environment::CreateVariable<Instance>(s_vulkanInstanceKey);
|
||||
}
|
||||
}
|
||||
|
||||
return s_vulkanInstance.Get();
|
||||
}
|
||||
|
||||
void Instance::Reset()
|
||||
{
|
||||
s_vulkanInstance.Reset();
|
||||
}
|
||||
|
||||
Instance::~Instance()
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace AZ
|
||||
};
|
||||
|
||||
static Instance& GetInstance();
|
||||
static void Reset();
|
||||
~Instance();
|
||||
bool Init(const Descriptor& descriptor);
|
||||
void Shutdown();
|
||||
|
||||
@@ -101,6 +101,7 @@ namespace AZ
|
||||
RHI::FactoryManagerBus::Broadcast(&RHI::FactoryManagerRequest::UnregisterFactory, this);
|
||||
|
||||
Instance::GetInstance().Shutdown();
|
||||
Instance::Reset();
|
||||
}
|
||||
|
||||
Name SystemComponent::GetName()
|
||||
|
||||
@@ -90,6 +90,9 @@ namespace AudioSystemGem
|
||||
|
||||
AudioSystemGemSystemComponent::~AudioSystemGemSystemComponent()
|
||||
{
|
||||
// The audio system uses the Audio::AudioSystemAllocator
|
||||
// so it needs to be deleted before the allocator is shutdown
|
||||
m_audioSystem.reset();
|
||||
Audio::Platform::ShutdownAudioAllocators();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/std/containers/fixed_unordered_map.h>
|
||||
#include <AzFramework/Input/Buses/Requests/InputTextEntryRequestBus.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
@@ -31,11 +32,11 @@ using namespace AzFramework;
|
||||
using namespace ImGui;
|
||||
|
||||
// Wheel Delta const value.
|
||||
const constexpr uint32_t IMGUI_WHEEL_DELTA = 120; // From WinUser.h, for Linux
|
||||
static const constexpr uint32_t IMGUI_WHEEL_DELTA = 120; // From WinUser.h, for Linux
|
||||
|
||||
// Typedef and local static map to hold LyInput->ImGui Nav mappings ( filled up in Initialize() )
|
||||
typedef AZStd::pair<AzFramework::InputChannelId, ImGuiNavInput_> LyButtonImGuiNavIndexPair;
|
||||
typedef AZStd::unordered_map<AzFramework::InputChannelId, ImGuiNavInput_> LyButtonImGuiNavIndexMap;
|
||||
using LyButtonImGuiNavIndexPair = AZStd::pair<AzFramework::InputChannelId, ImGuiNavInput_>;
|
||||
using LyButtonImGuiNavIndexMap = AZStd::fixed_unordered_map<AzFramework::InputChannelId, ImGuiNavInput_, 11, 32>;
|
||||
static LyButtonImGuiNavIndexMap s_lyInputToImGuiNavIndexMap;
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <LyShine/Animation/IUiAnimation.h>
|
||||
#include "UiAnimationSystem.h"
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
|
||||
|
||||
/*!
|
||||
@@ -39,7 +40,7 @@ public:
|
||||
, valueType(_valueType)
|
||||
, flags(_flags) {};
|
||||
|
||||
AZStd::string name; // parameter name.
|
||||
AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator> name; // parameter name.
|
||||
CUiAnimParamType paramType; // parameter id.
|
||||
EUiAnimValue valueType; // value type, defines type of track to use for animating this parameter.
|
||||
ESupportedParamFlags flags; // combination of flags from ESupportedParamFlags.
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
#include "UiAnimSerialize.h"
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <StlUtils.h>
|
||||
|
||||
#include <StaticInstance.h>
|
||||
#include <ISystem.h>
|
||||
#include <ILog.h>
|
||||
#include <IConsole.h>
|
||||
@@ -25,22 +27,31 @@
|
||||
#include <IViewSystem.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Serialization for anim nodes & param types
|
||||
#define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.find(eUiAnimNodeType_ ## name) == g_animNodeEnumToStringMap.end()); \
|
||||
g_animNodeEnumToStringMap[eUiAnimNodeType_ ## name] = AZ_STRINGIZE(name); \
|
||||
g_animNodeStringToEnumMap[AZStd::string(AZ_STRINGIZE(name))] = eUiAnimNodeType_ ## name;
|
||||
namespace
|
||||
{
|
||||
using UiAnimParamSystemString = AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator>;
|
||||
|
||||
#define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.find(eUiAnimParamType_ ## name) == g_animParamEnumToStringMap.end()); \
|
||||
template <typename KeyType, typename MappedType, typename Compare = AZStd::less<KeyType>>
|
||||
using UiAnimSystemOrderedMap = AZStd::map<KeyType, MappedType, Compare, AZStd::stateless_allocator>;
|
||||
template <typename KeyType, typename MappedType, typename Hasher = AZStd::hash<KeyType>, typename EqualKey = AZStd::equal_to<KeyType>>
|
||||
using UiAnimSystemUnorderedMap = AZStd::unordered_map<KeyType, MappedType, Hasher, EqualKey, AZStd::stateless_allocator>;
|
||||
}
|
||||
// Serialization for anim nodes & param types
|
||||
#define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.contains(eUiAnimNodeType_ ## name)); \
|
||||
g_animNodeEnumToStringMap[eUiAnimNodeType_ ## name] = AZ_STRINGIZE(name); \
|
||||
g_animNodeStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimNodeType_ ## name;
|
||||
|
||||
#define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.contains(eUiAnimParamType_ ## name)); \
|
||||
g_animParamEnumToStringMap[eUiAnimParamType_ ## name] = AZ_STRINGIZE(name); \
|
||||
g_animParamStringToEnumMap[AZStd::string(AZ_STRINGIZE(name))] = eUiAnimParamType_ ## name;
|
||||
g_animParamStringToEnumMap[UiAnimParamSystemString(AZ_STRINGIZE(name))] = eUiAnimParamType_ ## name;
|
||||
|
||||
namespace
|
||||
{
|
||||
AZStd::unordered_map<int, AZStd::string> g_animNodeEnumToStringMap;
|
||||
StaticInstance<std::map<AZStd::string, EUiAnimNodeType, stl::less_stricmp<AZStd::string> >> g_animNodeStringToEnumMap;
|
||||
UiAnimSystemUnorderedMap<int, UiAnimParamSystemString> g_animNodeEnumToStringMap;
|
||||
UiAnimSystemOrderedMap<UiAnimParamSystemString, EUiAnimNodeType, stl::less_stricmp<UiAnimParamSystemString>> g_animNodeStringToEnumMap;
|
||||
|
||||
AZStd::unordered_map<int, AZStd::string> g_animParamEnumToStringMap;
|
||||
StaticInstance<std::map<AZStd::string, EUiAnimParamType, stl::less_stricmp<AZStd::string> >> g_animParamStringToEnumMap;
|
||||
UiAnimSystemUnorderedMap<int, UiAnimParamSystemString> g_animParamEnumToStringMap;
|
||||
UiAnimSystemOrderedMap<UiAnimParamSystemString, EUiAnimParamType, stl::less_stricmp<UiAnimParamSystemString>> g_animParamStringToEnumMap;
|
||||
|
||||
// If you get an assert in this function, it means two node types have the same enum value.
|
||||
void RegisterNodeTypes()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
#include "AnimPostFXNode.h"
|
||||
#include "AnimSplineTrack.h"
|
||||
#include "CompoundSplineTrack.h"
|
||||
@@ -38,7 +39,7 @@ public:
|
||||
virtual void GetDefault(bool& val) const = 0;
|
||||
virtual void GetDefault(Vec4& val) const = 0;
|
||||
|
||||
AZStd::string m_name;
|
||||
AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator> m_name;
|
||||
|
||||
protected:
|
||||
virtual ~CControlParamBase(){}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/std/allocator_stateless.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzFramework/Components/CameraBus.h>
|
||||
#include <Maestro/Bus/SequenceComponentBus.h>
|
||||
#include "Movie.h"
|
||||
@@ -73,22 +76,32 @@ static SMovieSequenceAutoComplete s_movieSequenceAutoComplete;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Serialization for anim nodes & param types
|
||||
#define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.find(AnimNodeType::name) == g_animNodeEnumToStringMap.end()); \
|
||||
g_animNodeEnumToStringMap[AnimNodeType::name] = AZ_STRINGIZE(name); \
|
||||
g_animNodeStringToEnumMap[AZStd::string(AZ_STRINGIZE(name))] = AnimNodeType::name;
|
||||
namespace
|
||||
{
|
||||
using AnimParamSystemString = AZStd::basic_string<char, AZStd::char_traits<char>, AZStd::stateless_allocator>;
|
||||
|
||||
#define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.find(AnimParamType::name) == g_animParamEnumToStringMap.end()); \
|
||||
g_animParamEnumToStringMap[AnimParamType::name] = AZ_STRINGIZE(name); \
|
||||
g_animParamStringToEnumMap[AZStd::string(AZ_STRINGIZE(name))] = AnimParamType::name;
|
||||
template <typename KeyType, typename MappedType, typename Compare = AZStd::less<KeyType>>
|
||||
using AnimSystemOrderedMap = AZStd::map<KeyType, MappedType, Compare, AZStd::stateless_allocator>;
|
||||
template <typename KeyType, typename MappedType, typename Hasher = AZStd::hash<KeyType>, typename EqualKey = AZStd::equal_to<KeyType>>
|
||||
using AnimSystemUnorderedMap = AZStd::unordered_map<KeyType, MappedType, Hasher, EqualKey, AZStd::stateless_allocator>;
|
||||
}
|
||||
|
||||
// Serialization for anim nodes & param types
|
||||
#define REGISTER_NODE_TYPE(name) assert(g_animNodeEnumToStringMap.contains(AnimNodeType::name)); \
|
||||
g_animNodeEnumToStringMap[AnimNodeType::name] = AZ_STRINGIZE(name); \
|
||||
g_animNodeStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimNodeType::name;
|
||||
|
||||
#define REGISTER_PARAM_TYPE(name) assert(g_animParamEnumToStringMap.contains(AnimParamType::name)); \
|
||||
g_animParamEnumToStringMap[AnimParamType::name] = AZ_STRINGIZE(name); \
|
||||
g_animParamStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimParamType::name;
|
||||
|
||||
namespace
|
||||
{
|
||||
AZStd::unordered_map<AnimNodeType, AZStd::string> g_animNodeEnumToStringMap;
|
||||
StaticInstance<std::map<AZStd::string, AnimNodeType, stl::less_stricmp<AZStd::string> >> g_animNodeStringToEnumMap;
|
||||
AnimSystemUnorderedMap<AnimNodeType, AnimParamSystemString> g_animNodeEnumToStringMap;
|
||||
AnimSystemOrderedMap<AnimParamSystemString, AnimNodeType, stl::less_stricmp<AnimParamSystemString>> g_animNodeStringToEnumMap;
|
||||
|
||||
AZStd::unordered_map<AnimParamType, AZStd::string> g_animParamEnumToStringMap;
|
||||
StaticInstance<std::map<AZStd::string, AnimParamType, stl::less_stricmp<AZStd::string> >> g_animParamStringToEnumMap;
|
||||
AnimSystemUnorderedMap<AnimParamType, AnimParamSystemString> g_animParamEnumToStringMap;
|
||||
AnimSystemOrderedMap<AnimParamSystemString, AnimParamType, stl::less_stricmp<AnimParamSystemString>> g_animParamStringToEnumMap;
|
||||
|
||||
// If you get an assert in this function, it means two node types have the same enum value.
|
||||
void RegisterNodeTypes()
|
||||
|
||||
Reference in New Issue
Block a user