Merge branch 'development' into memory/overrideshim_removal

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Framework/AzCore/AzCore/Memory/AllocatorBase.cpp
#	Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapAllocator.cpp
#	Code/Framework/AzCore/AzCore/Memory/BestFitExternalMapSchema.cpp
#	Code/Framework/AzCore/AzCore/Memory/PoolSchema.cpp
#	Code/Framework/AzCore/AzCore/Memory/SystemAllocator.cpp
#	Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp
This commit is contained in:
Esteban Papp
2022-01-05 11:34:52 -08:00
1267 changed files with 157305 additions and 27177 deletions
@@ -11,6 +11,7 @@
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
using namespace AZ;
@@ -408,4 +409,118 @@ namespace UnitTest
Matrix4x4 m = Matrix4x4::CreateFromQuaternion(rotQuat);
AZ_TEST_ASSERT(m.IsClose(rotMatrix));
}
class QuaternionScaledAxisAngleConversionFixture
: public ::testing::TestWithParam<AZ::Quaternion>
{
public:
AZ::Quaternion GetAbs(const AZ::Quaternion& in)
{
// Take the shortest path for quaternions containing rotations bigger than 180.0°.
if (in.GetW() < 0.0f)
{
return -in;
}
return in;
}
};
static const AZ::Quaternion RotationRepresentationConversionTestQuats[] =
{
AZ::Quaternion::CreateIdentity(),
-AZ::Quaternion::CreateIdentity(),
AZ::Quaternion::CreateRotationX(AZ::Constants::TwoPi),
AZ::Quaternion::CreateRotationY(AZ::Constants::Pi),
AZ::Quaternion::CreateRotationZ(AZ::Constants::HalfPi),
AZ::Quaternion::CreateRotationX(AZ::Constants::QuarterPi),
AZ::Quaternion(0.64f, 0.36f, 0.48f, 0.48f),
AZ::Quaternion(0.70f, -0.34f, 0.10f, 0.62f),
AZ::Quaternion(-0.38f, 0.34f, 0.70f, -0.50f),
AZ::Quaternion(0.70f, -0.34f, -0.38f, 0.50f),
AZ::Quaternion(0.00f, 0.00f, -0.28f, 0.96f),
AZ::Quaternion(0.24f, -0.64f, 0.72f, 0.12f),
AZ::Quaternion(-0.66f, 0.62f, 0.42f, 0.06f)
};
TEST_P(QuaternionScaledAxisAngleConversionFixture, ScaledAxisAngleQuatRoundtripTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to scaled axis-angle representation.
const AZ::Vector3 scaledAxisAngle = testQuat.ConvertToScaledAxisAngle();
// Convert the scaled axis-angle back into a quaternion.
AZ::Quaternion backFromScaledAxisAngle = AZ::Quaternion::CreateFromScaledAxisAngle(scaledAxisAngle);
// Compare the original quaternion with the one after the conversion.
EXPECT_THAT(testQuat, IsCloseTolerance(backFromScaledAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, AxisAngleQuatRoundtripTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to axis-angle representation.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
// Convert the axis-angle back into a quaternion and compare the original quaternion with the one after the conversion.
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axis, angle);
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareAxisAngleConversionTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to scaled axis-angle representation.
const AZ::Vector3 scaledAxisAngle = testQuat.ConvertToScaledAxisAngle();
// Convert test quaternion to axis-angle representation and scale it manually.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
// Compare the scaled result to the version from the helper that directly converts it to scaled axis-angle.
AZ::Vector3 scaledResult = axis*angle;
EXPECT_TRUE(scaledResult.IsClose(scaledAxisAngle, 1e-5f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareScaledAxisAngleConversionTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to axis-angle representation and scale it manually.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
AZ::Vector3 scaledResult = axis*angle;
// Special case handling for identity rotation.
AZ::Vector3 axisFromScaledResult = scaledResult.GetNormalized();
float angleFromScaledResult = scaledResult.GetLength();
if (AZ::IsClose(angleFromScaledResult, 0.0f))
{
axisFromScaledResult = AZ::Vector3::CreateAxisY();
}
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axisFromScaledResult, angleFromScaledResult);
EXPECT_THAT(testQuat, IsCloseTolerance(backFromAxisAngle, 1e-6f));
}
INSTANTIATE_TEST_CASE_P(MATH_Quaternion, QuaternionScaledAxisAngleConversionFixture, ::testing::ValuesIn(RotationRepresentationConversionTestQuats));
TEST(MATH_Quaternion, ShortestEquivalent)
{
const AZ::Quaternion testQuat = AZ::Quaternion::CreateRotationX(AZ::Constants::HalfPi * 3.0f);
AZ::Quaternion absQuat = testQuat;
absQuat.ShortestEquivalent();
EXPECT_THAT(testQuat.GetShortestEquivalent(), IsCloseTolerance(absQuat, 1e-6f));
const float angle = absQuat.GetEulerRadians().GetX();
EXPECT_THAT(angle, testing::FloatEq(-AZ::Constants::HalfPi));
}
}
@@ -0,0 +1,31 @@
/*
* 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/PlatformIncl.h>
#include <AzCore/Debug/Trace.h>
#include <malloc.h>
#include <sys/resource.h>
namespace Benchmark
{
namespace Platform
{
size_t GetProcessMemoryUsageBytes()
{
struct rusage rusage;
getrusage(RUSAGE_SELF, &rusage);
return rusage.ru_maxrss * 1024L;
}
size_t GetMemorySize(void* memory)
{
return memory ? malloc_usable_size(memory) : 0;
}
}
}
@@ -8,4 +8,5 @@
set(FILES
Tests/UtilsTests_Android.cpp
Tests/Memory/AllocatorBenchmarks_Android.cpp
)
@@ -327,17 +327,13 @@ namespace JsonSerializationTests
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
}
#if GTEST_HAS_DEATH_TEST
using JsonSerializationDeathTests = JsonRegistrationContextTests;
TEST_F(JsonSerializationDeathTests, DoubleUnregisterSerializer_Asserts)
TEST_F(JsonRegistrationContextTests, DoubleUnregisterSerializer_Asserts)
{
ASSERT_DEATH({
SerializerWithOneType::Reflect(m_jsonRegistrationContext.get());
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
}, ".*"
);
SerializerWithOneType::Reflect(m_jsonRegistrationContext.get());
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
AZ_TEST_START_ASSERTTEST;
SerializerWithOneType::Unreflect(m_jsonRegistrationContext.get());
AZ_TEST_STOP_ASSERTTEST(1);
}
#endif // GTEST_HAS_DEATH_TEST
} //namespace JsonSerializationTests
@@ -0,0 +1,106 @@
/*
* 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/IO/Path/Path.h>
#include <AzCore/IO/Path/PathReflect.h>
#include <AzCore/Serialization/Json/PathSerializer.h>
#include <Tests/Serialization/Json/BaseJsonSerializerFixture.h>
#include <Tests/Serialization/Json/JsonSerializerConformityTests.h>
namespace JsonSerializationTests
{
template<typename PathType>
class PathTestDescription
: public JsonSerializerConformityTestDescriptor<PathType>
{
public:
using JsonSerializerConformityTestDescriptor<PathType>::Reflect;
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& serializeContext) override
{
AZ::IO::PathReflect(serializeContext.get());
}
void Reflect(AZStd::unique_ptr<AZ::JsonRegistrationContext>& jsonContext) override
{
AZ::IO::PathReflect(jsonContext.get());
}
AZStd::shared_ptr<AZ::BaseJsonSerializer> CreateSerializer() override
{
return AZStd::make_shared<AZ::JsonPathSerializer>();
}
AZStd::shared_ptr<PathType> CreateDefaultInstance() override
{
return AZStd::make_shared<PathType>();
}
AZStd::shared_ptr<PathType> CreateFullySetInstance() override
{
return AZStd::make_shared<PathType>("O3DE/Relative/Path");
}
AZStd::string_view GetJsonForFullySetInstance() override
{
return R"("O3DE/Relative/Path")";
}
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
{
features.EnableJsonType(rapidjson::kStringType);
features.m_supportsPartialInitialization = false;
features.m_supportsInjection = false;
}
bool AreEqual(const PathType& lhs, const PathType& rhs) override
{
return lhs == rhs;
}
};
using PathConformityTestTypes = ::testing::Types<
PathTestDescription<AZ::IO::Path>,
PathTestDescription<AZ::IO::FixedMaxPath>
>;
INSTANTIATE_TYPED_TEST_CASE_P(Path, JsonSerializerConformityTests, PathConformityTestTypes);
class PathSerializerTests
: public BaseJsonSerializerFixture
{
public:
AZStd::unique_ptr<AZ::JsonPathSerializer> m_serializer;
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
m_serializer = AZStd::make_unique<AZ::JsonPathSerializer>();
}
void TearDown() override
{
m_serializer.reset();
BaseJsonSerializerFixture::TearDown();
}
};
TEST_F(PathSerializerTests, LoadingIntoFixedMaxPath_GreaterThanMaxPathLength_Fails)
{
AZ::IO::Path testPath;
// Fill a path greater than the AZ::IO::MaxPathLength in write it to Json
testPath.Native().append(AZ::IO::MaxPathLength + 2, 'a');
rapidjson::Value loadPathValue;
AZ::JsonSerializationResult::ResultCode resultCode = m_serializer->Store(loadPathValue,
&testPath, nullptr, azrtti_typeid<AZ::IO::Path>(), *m_jsonSerializationContext);
EXPECT_EQ(AZ::JsonSerializationResult::Outcomes::Success, resultCode.GetOutcome());
AZ::IO::FixedMaxPath resultPath;
AZ::JsonSerializationResult::ResultCode result = m_serializer->Load(&resultPath, azrtti_typeid<AZ::IO::FixedMaxPath>(),
loadPathValue, *m_jsonDeserializationContext);
EXPECT_GE(result.GetOutcome(), AZ::JsonSerializationResult::Outcomes::Invalid);
}
} // namespace JsonSerializationTests
@@ -10,6 +10,77 @@
#include <Tests/Serialization/Json/JsonSerializationTests.h>
#include <Tests/Serialization/Json/TestCases_Classes.h>
#include <Tests/Serialization/Json/TestCases_Pointers.h>
#include <AzCore/Asset/AssetCommon.h>
namespace AZ
{
template<typename T>
struct SerializeGenericTypeInfo<JsonSerializationTests::TemplatedClass<T>>
{
using ThisType = JsonSerializationTests::TemplatedClass<T>;
class GenericTemplatedClassInfo : public GenericClassInfo
{
public:
GenericTemplatedClassInfo()
: m_classData{ SerializeContext::ClassData::Create<ThisType>(
"TemplatedClass", "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", nullptr, nullptr) }
{
}
SerializeContext::ClassData* GetClassData() override
{
return &m_classData;
}
size_t GetNumTemplatedArguments() override
{
return 1;
}
const Uuid& GetSpecializedTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetGenericTypeId() const override
{
return m_classData.m_typeId;
}
const Uuid& GetTemplatedTypeId(size_t element) override
{
(void)element;
return SerializeGenericTypeInfo<T>::GetClassTypeId();
}
void Reflect(SerializeContext* serializeContext) override
{
if (serializeContext)
{
serializeContext->RegisterGenericClassInfo(
GetSpecializedTypeId(), this, &AZ::AnyTypeInfoConcept<Data::Asset<Data::AssetData>>::CreateAny);
serializeContext->RegisterGenericClassInfo(
azrtti_typeid<ThisType>(), this,
&AZ::AnyTypeInfoConcept<ThisType>::CreateAny);
}
}
SerializeContext::ClassData m_classData;
};
using ClassInfoType = GenericTemplatedClassInfo;
static ClassInfoType* GetGenericInfo()
{
return GetCurrentSerializeContextModule().CreateGenericClassInfo<ThisType>();
}
static const Uuid& GetClassTypeId()
{
return GetGenericInfo()->GetClassData()->m_typeId;
}
};
} // namespace AZ
namespace JsonSerializationTests
{
@@ -286,4 +357,32 @@ namespace JsonSerializationTests
EXPECT_EQ(Processing::Halted, result.GetProcessing());
EXPECT_EQ(Outcomes::Unknown, result.GetOutcome());
}
TEST_F(JsonSerializationTests, StoreTypeId_TemplatedType_StoresUuidWithName)
{
using namespace AZ;
using namespace AZ::JsonSerializationResult;
m_serializeContext->RegisterGenericType<TemplatedClass<A::Inherited>>();
m_serializeContext->RegisterGenericType<TemplatedClass<BaseClass>>();
Uuid input = azrtti_typeid<TemplatedClass<A::Inherited>>();
ResultCode result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
AZStd::string expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<A::Inherited>>().ToString<AZStd::string>().c_str());
Expect_DocStrEq(expected.c_str(), false);
input = azrtti_typeid<TemplatedClass<BaseClass>>();
result = JsonSerialization::StoreTypeId(
*m_jsonDocument, m_jsonDocument->GetAllocator(), input, AZStd::string_view{}, *m_serializationSettings);
expected =
AZStd::string::format(R"("%s TemplatedClass")", azrtti_typeid<TemplatedClass<BaseClass>>().ToString<AZStd::string>().c_str());
EXPECT_EQ(Processing::Completed, result.GetProcessing());
Expect_DocStrEq(expected.c_str(), false);
}
} // namespace JsonSerializationTests
@@ -89,7 +89,7 @@ namespace AZ::IO
m_context = nullptr;
AllocatorInstance<ThreadPoolAllocator>::Destroy();
AllocatorInstance<PoolAllocator>::Destroy();
AllocatorInstance<PoolAllocator>::Destroy();
UnitTest::AllocatorsFixture::TearDown();
}
@@ -123,7 +123,7 @@ namespace AZ::IO
.WillRepeatedly(Return(false));
EXPECT_CALL(*m_mock, QueueRequest(_));
EXPECT_CALL(*m_mock, UpdateStatus(_)).Times(AnyNumber());
switch (mockResult)
{
case ReadResult::Success:
@@ -267,7 +267,7 @@ namespace AZ::IO
{
allCompleted = allCompleted && request.GetStatus() == IStreamerTypes::RequestStatus::Completed;
};
FileRequest* requests[count];
AZStd::unique_ptr<u32[]> buffers[count];
for (size_t i = 0; i < count; ++i)
@@ -300,7 +300,7 @@ namespace AZ::IO
size = size >> 2;
for (u64 i = 0; i < size; ++i)
{
// Using assert here because in case of a problem EXPECT would
// Using assert here because in case of a problem EXPECT would
// cause a large amount of log noise.
ASSERT_EQ(buffer[i], offset + (i << 2));
}
@@ -359,7 +359,7 @@ namespace AZ::IO
.Times(2)
.WillRepeatedly([this](FileRequest* request) { m_context.MarkRequestAsCompleted(request); });
m_context.FinalizeCompletedRequests();
azfree(memory);
}
@@ -415,7 +415,7 @@ namespace AZ::IO
m_context.FinalizeCompletedRequests();
EXPECT_EQ(2, completedRequests);
azfree(memory1);
azfree(memory0);
}
@@ -30,7 +30,7 @@ namespace AZ::IO
{
using ::testing::_;
using ::testing::AnyNumber;
UnitTest::AllocatorsFixture::SetUp();
m_mock = AZStd::make_shared<StreamStackEntryMock>();
@@ -78,7 +78,7 @@ namespace AZ::IO
{
using ::testing::_;
using ::testing::AtLeast;
EXPECT_CALL(*m_mock, UpdateStatus(_)).Times(AtLeast(1));
EXPECT_CALL(*m_mock, UpdateCompletionEstimates(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(*m_mock, PrepareRequest(_))
@@ -115,7 +115,7 @@ namespace AZ::IO
void MockAllocatorForUnclaimedMemory(IStreamerTypes::RequestMemoryAllocatorMock& mock, AZStd::binary_semaphore& sync)
{
using ::testing::_;
EXPECT_CALL(mock, LockAllocator()).Times(1);
EXPECT_CALL(mock, UnlockAllocator())
.Times(1)
@@ -256,13 +256,13 @@ namespace AZ::IO
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Return;
EXPECT_CALL(*m_mock, UpdateStatus(_)).Times(AtLeast(1));
EXPECT_CALL(*m_mock, UpdateCompletionEstimates(_, _, _, _)).Times(AtLeast(1));
EXPECT_CALL(*m_mock, PrepareRequest(_)).Times(AtLeast(1));
EXPECT_CALL(*m_mock, ExecuteRequests()).Times(AtLeast(1));
EXPECT_CALL(*m_mock, QueueRequest(_)).Times(1);
AZStd::atomic_int counter = 2;
AZStd::binary_semaphore sync;
auto wait = [&sync, &counter](FileRequestHandle)
@@ -350,7 +350,7 @@ namespace AZ::IO
EXPECT_CALL(*m_mock, UpdateStatus(_)).Times(AnyNumber());
EXPECT_CALL(*m_mock, UpdateCompletionEstimates(_, _, _, _)).Times(AnyNumber());
// Pretend to be busy [Iterations] times, then set the status to idle so the Scheduler thread can exit.
EXPECT_CALL(*m_mock, ExecuteRequests())
.Times(Iterations + 1)
@@ -97,7 +97,7 @@ namespace AZ::IO
TYPED_TEST_P(StreamStackEntryConformityTests, SetContext_ContextIsForwardedToNext_SetContextOnMockIsCalled)
{
using ::testing::_;
auto mock = AZStd::make_shared<StreamStackEntryMock>();
auto entry = this->m_description.CreateInstance();
entry.SetNext(mock);
@@ -194,14 +194,14 @@ namespace AZ::IO
TYPED_TEST_P(StreamStackEntryConformityTests, UpdateStatus_ForwardsCallToNext_NextRecievedCall)
{
using ::testing::_;
auto mock = AZStd::make_shared<StreamStackEntryMock>();
auto entry = this->m_description.CreateInstance();
entry.SetNext(mock);
EXPECT_CALL(*mock, UpdateStatus(_))
.Times(1);
StreamStackEntry::Status status;
entry.UpdateStatus(status);
}
@@ -241,7 +241,7 @@ namespace AZ::IO
TYPED_TEST_P(StreamStackEntryConformityTests, UpdateStatus_NextHasSmallerNumSlots_ReturnsSmallestNumSlots)
{
using ::testing::_;
if (this->m_description.UsesSlots())
{
auto mock = AZStd::make_shared<StreamStackEntryMock>();
@@ -264,7 +264,7 @@ namespace AZ::IO
TYPED_TEST_P(StreamStackEntryConformityTests, UpdateStatus_NextHasLargerNumSlots_ReturnsSmallestNumSlots)
{
using ::testing::_;
if (this->m_description.UsesSlots())
{
auto mock = AZStd::make_shared<StreamStackEntryMock>();
@@ -289,7 +289,7 @@ namespace AZ::IO
TYPED_TEST_P(StreamStackEntryConformityTests, UpdateCompletionEstimates_ForwardsCallToNext_NextRecievedCall)
{
using ::testing::_;
auto mock = AZStd::make_shared<StreamStackEntryMock>();
auto entry = this->m_description.CreateInstance();
entry.SetNext(mock);
File diff suppressed because it is too large Load Diff
@@ -11,8 +11,7 @@
namespace UnitTest
{
class TimeTests
: public AllocatorsFixture
class TimeTests : public AllocatorsFixture
{
public:
void SetUp() override
@@ -77,4 +76,4 @@ namespace UnitTest
int64_t delta = static_cast<int64_t>(timeMs) - static_cast<int64_t>(timeUsToMs);
EXPECT_LT(abs(delta), 1);
}
}
} // namespace UnitTest
@@ -111,6 +111,7 @@ set(FILES
Serialization/Json/MapSerializerTests.cpp
Serialization/Json/MathVectorSerializerTests.cpp
Serialization/Json/MathMatrixSerializerTests.cpp
Serialization/Json/PathSerializerTests.cpp
Serialization/Json/SmartPointerSerializerTests.cpp
Serialization/Json/StringSerializerTests.cpp
Serialization/Json/TestCases.h