Merge branch 'development' into cmake/AddressSanitizer

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

# Conflicts:
#	Code/Legacy/CryCommon/LegacyAllocator.h
This commit is contained in:
Esteban Papp
2021-08-19 11:44:28 -07:00
460 changed files with 4366 additions and 5622 deletions
@@ -7,10 +7,14 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
# fmt:off
class Tests():
create_new_entity = ("Entity: 'CreateNewEntity' passed", "Entity: 'CreateNewEntity' failed")
create_prefab = ("Prefab: 'CreatePrefab' passed", "Prefab: 'CreatePrefab' failed")
instantiate_prefab = ("Prefab: 'InstantiatePrefab' passed", "Prefab: 'InstantiatePrefab' failed")
new_prefab_position = ("Prefab: new prefab's position is at the expected position", "Prefab: new prefab's position is *not* at the expected position")
create_new_entity = ("'CreateNewEntity' passed", "'CreateNewEntity' failed")
create_prefab = ("'CreatePrefab' passed", "'CreatePrefab' failed")
instantiate_prefab = ("'InstantiatePrefab' passed", "'InstantiatePrefab' failed")
has_one_child = ("instantiated prefab contains only one child as expected", "instantiated prefab does *not* contain only one child as expected")
instantiated_prefab_position = ("instantiated prefab's position is at the expected position", "instantiated prefab's position is *not* at the expected position")
delete_prefab = ("'DeleteEntitiesAndAllDescendantsInInstance' passed", "'DeleteEntitiesAndAllDescendantsInInstance' failed")
instantiated_prefab_removed = ("instantiated prefab's container entity has been removed", "instantiated prefab's container entity has *not* been removed")
instantiated_child_removed = ("instantiated prefab's child entity has been removed", "instantiated prefab's child entity has *not* been removed")
# fmt:on
def PrefabLevel_BasicWorkflow():
@@ -18,6 +22,7 @@ def PrefabLevel_BasicWorkflow():
This test will help verify if the following functions related to Prefab work as expected:
- CreatePrefab
- InstantiatePrefab
- DeleteEntitiesAndAllDescendantsInInstance
"""
import os
@@ -35,31 +40,68 @@ def PrefabLevel_BasicWorkflow():
from azlmbr.math import Vector3
import azlmbr.legacy.general as general
EXPECTED_NEW_PREFAB_POSITION = Vector3(10.00, 20.0, 30.0)
NEW_PREFAB_NAME = "new_prefab"
NEW_PREFAB_FILE_NAME = NEW_PREFAB_NAME + ".prefab"
NEW_PREFAB_FILE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), NEW_PREFAB_FILE_NAME)
INSTANTIATED_PREFAB_POSITION = Vector3(10.00, 20.0, 30.0)
INSTANTIATED_PREFAB_NAME = "instantiated_prefab"
INSTANTIATED_CHILD_ENTITY_NAME = "child_1"
TEST_LEVEL_FOLDER = "Prefab"
TEST_LEVEL_NAME = "Base"
def find_entity_by_name(entity_name):
searchFilter = entity.SearchFilter()
searchFilter.names = [entity_name]
entityIds = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if entityIds and entityIds[0].IsValid():
return entityIds[0]
return None
def print_error_if_failed(prefab_operation_result):
if not prefab_operation_result.IsSuccess():
Report.info(f'Error message: {prefab_operation_result.GetError()}')
# Open the test level
helper.init_idle()
helper.open_level("Prefab", "Base")
helper.open_level(TEST_LEVEL_FOLDER, TEST_LEVEL_NAME)
# Create a new Entity at the root level
new_entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', EntityId())
Report.result(Tests.create_new_entity, new_entity_id.IsValid())
# Checks for prefab creation passed or not
new_prefab_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'new_prefab.prefab')
create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', [new_entity_id], new_prefab_file_path)
Report.result(Tests.create_prefab, create_prefab_result)
create_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'CreatePrefabInMemory', [new_entity_id], NEW_PREFAB_FILE_PATH)
Report.result(Tests.create_prefab, create_prefab_result.IsSuccess())
print_error_if_failed(create_prefab_result)
# Checks for prefab instantiation passed or not
container_entity_id = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', new_prefab_file_path, EntityId(), EXPECTED_NEW_PREFAB_POSITION)
Report.result(Tests.instantiate_prefab, container_entity_id.IsValid())
instantiate_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'InstantiatePrefab', NEW_PREFAB_FILE_PATH, EntityId(), INSTANTIATED_PREFAB_POSITION)
Report.result(Tests.instantiate_prefab, instantiate_prefab_result.IsSuccess() and instantiate_prefab_result.GetValue().IsValid())
print_error_if_failed(instantiate_prefab_result)
container_entity_id = instantiate_prefab_result.GetValue()
editor.EditorEntityAPIBus(bus.Event, 'SetName', container_entity_id, INSTANTIATED_PREFAB_NAME)
children_entity_ids = editor.EditorEntityInfoRequestBus(bus.Event, 'GetChildren', container_entity_id)
Report.result(Tests.has_one_child, len(children_entity_ids) is 1)
child_entity_id = children_entity_ids[0]
editor.EditorEntityAPIBus(bus.Event, 'SetName', child_entity_id, INSTANTIATED_CHILD_ENTITY_NAME)
# Checks if the new prefab is at the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log
new_prefab_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", container_entity_id)
is_at_position = new_prefab_position.IsClose(EXPECTED_NEW_PREFAB_POSITION)
Report.result(Tests.new_prefab_position, is_at_position)
actual_prefab_position = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", container_entity_id)
is_at_position = actual_prefab_position.IsClose(INSTANTIATED_PREFAB_POSITION)
Report.result(Tests.instantiated_prefab_position, is_at_position)
if not is_at_position:
Report.info(f'Expected position: {EXPECTED_NEW_PREFAB_POSITION.ToString()}, actual position: {new_prefab_position.ToString()}')
Report.info(f'Expected position: {INSTANTIATED_PREFAB_POSITION.ToString()}, actual position: {actual_prefab_position.ToString()}')
# Checks for prefab deletion passed or not
delete_prefab_result = prefab.PrefabPublicRequestBus(bus.Broadcast, 'DeleteEntitiesAndAllDescendantsInInstance', [container_entity_id])
Report.result(Tests.delete_prefab, delete_prefab_result.IsSuccess())
print_error_if_failed(delete_prefab_result)
Report.result(Tests.instantiated_prefab_removed, find_entity_by_name(INSTANTIATED_PREFAB_NAME) is None)
Report.result(Tests.instantiated_child_removed, find_entity_by_name(INSTANTIATED_CHILD_ENTITY_NAME) is None)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
+1
View File
@@ -242,6 +242,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
Legacy::CryCommon
AZ::AzToolsFramework
AZ::AzToolsFramework.Tests
AZ::AzFrameworkTestShared
AZ::AzToolsFrameworkTestCommon
Legacy::EditorLib
Gem::AtomToolsFramework.Static
+12 -48
View File
@@ -32,9 +32,6 @@
#include <AzToolsFramework/API/EditorLevelNotificationBus.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
// CryCommon
#include <CryCommon/IAudioSystem.h>
// Editor
#include "Settings.h"
@@ -60,6 +57,7 @@
#include <Atom/RPI.Public/ViewportContextBus.h>
// LmbrCentral
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
#include <LmbrCentral/Rendering/EditorLightComponentBus.h> // for LmbrCentral::EditorLightComponentRequestBus
//#define PROFILE_LOADING_WITH_VTUNE
@@ -269,20 +267,7 @@ void CCryEditDoc::DeleteContents()
CErrorReportDialog::Clear();
// Unload level specific audio binary data.
Audio::SAudioManagerRequestData<Audio::eAMRT_UNLOAD_AFCM_DATA_BY_SCOPE> oAMData(Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags = (Audio::eARF_PRIORITY_HIGH | Audio::eARF_EXECUTE_BLOCKING);
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
// Now unload level specific audio config data.
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_CONTROLS_DATA> oAMData2(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_PRELOADS_DATA> oAMData3(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData3;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::LevelUnloadAudio);
GetIEditor()->Notify(eNotify_OnSceneClosed);
CrySystemEventBus::Broadcast(&CrySystemEventBus::Events::OnCryEditorSceneClosed);
@@ -413,32 +398,11 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
#ifdef PROFILE_LOADING_WITH_VTUNE
VTResume();
#endif
// Parse level specific config data.
const char* controlsPath = nullptr;
Audio::AudioSystemRequestBus::BroadcastResult(controlsPath, &Audio::AudioSystemRequestBus::Events::GetControlsPath);
QString sAudioLevelPath(controlsPath);
sAudioLevelPath += "levels/";
AZStd::string const sLevelNameOnly = PathUtil::GetFileName(fileName.toUtf8().data());
sAudioLevelPath += sLevelNameOnly.c_str();
QByteArray path = sAudioLevelPath.toUtf8();
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_CONTROLS_DATA> oAMData(path, Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags = (Audio::eARF_PRIORITY_HIGH | Audio::eARF_EXECUTE_BLOCKING); // Needs to be blocking so data is available for next preloading request!
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_PRELOADS_DATA> oAMData2(path, Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::TAudioPreloadRequestID nPreloadRequestID = INVALID_AUDIO_PRELOAD_REQUEST_ID;
Audio::AudioSystemRequestBus::BroadcastResult(nPreloadRequestID, &Audio::AudioSystemRequestBus::Events::GetAudioPreloadRequestID, sLevelNameOnly.c_str());
if (nPreloadRequestID != INVALID_AUDIO_PRELOAD_REQUEST_ID)
{
Audio::SAudioManagerRequestData<Audio::eAMRT_PRELOAD_SINGLE_REQUEST> oAMData3(nPreloadRequestID);
oAudioRequestData.pData = &oAMData3;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
}
// Load level-specific audio data.
AZStd::string levelFileName{ fileName.toUtf8().constData() };
AZStd::to_lower(levelFileName.begin(), levelFileName.end());
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(
&LmbrCentral::AudioSystemComponentRequestBus::Events::LevelLoadAudio, AZStd::string_view{ levelFileName });
{
CAutoLogTime logtime("Game Engine level load");
@@ -1083,7 +1047,7 @@ static bool TryRenameFile(const QString& oldPath, const QString& newPath, int re
bool CCryEditDoc::SaveLevel(const QString& filename)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
QWaitCursor wait;
CAutoCheckOutDialogEnableForAll enableForAll;
@@ -1103,7 +1067,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel BackupBeforeSave");
AZ_PROFILE_SCOPE(AzToolsFramework, "CCryEditDoc::SaveLevel BackupBeforeSave");
BackupBeforeSave();
}
@@ -1214,7 +1178,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
CPakFile pakFile;
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Open PakFile");
AZ_PROFILE_SCOPE(AzToolsFramework, "CCryEditDoc::SaveLevel Open PakFile");
if (!pakFile.Open(tempSaveFile.toUtf8().data(), false))
{
gEnv->pLog->LogWarning("Unable to open pack file %s for writing", tempSaveFile.toUtf8().data());
@@ -1245,7 +1209,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
AZ::IO::ByteContainerStream<AZStd::vector<char>> entitySaveStream(&entitySaveBuffer);
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Save Entities To Stream");
AZ_PROFILE_SCOPE(AzToolsFramework, "CCryEditDoc::SaveLevel Save Entities To Stream");
EBUS_EVENT_RESULT(
savedEntities, AzToolsFramework::EditorEntityContextRequestBus, SaveToStreamForEditor, entitySaveStream, layerEntities,
instancesInLayers);
@@ -1259,7 +1223,7 @@ bool CCryEditDoc::SaveLevel(const QString& filename)
if (savedEntities)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "CCryEditDoc::SaveLevel Updated PakFile levelEntities.editor_xml");
AZ_PROFILE_SCOPE(AzToolsFramework, "CCryEditDoc::SaveLevel Updated PakFile levelEntities.editor_xml");
pakFile.UpdateFile("LevelEntities.editor_xml", entitySaveBuffer.begin(), entitySaveBuffer.size());
// Save XML archive to pak file.
+22
View File
@@ -31,6 +31,8 @@ namespace SandboxEditor
constexpr AZStd::string_view CameraPanSpeedSetting = "/Amazon/Preferences/Editor/Camera/PanSpeed";
constexpr AZStd::string_view CameraRotateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/RotateSmoothness";
constexpr AZStd::string_view CameraTranslateSmoothnessSetting = "/Amazon/Preferences/Editor/Camera/TranslateSmoothness";
constexpr AZStd::string_view CameraTranslateSmoothingSetting = "/Amazon/Preferences/Editor/Camera/TranslateSmoothing";
constexpr AZStd::string_view CameraRotateSmoothingSetting = "/Amazon/Preferences/Editor/Camera/RotateSmoothing";
constexpr AZStd::string_view CameraTranslateForwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateForwardId";
constexpr AZStd::string_view CameraTranslateBackwardIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateBackwardId";
constexpr AZStd::string_view CameraTranslateLeftIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateLeftId";
@@ -259,6 +261,26 @@ namespace SandboxEditor
SetRegistry(CameraTranslateSmoothnessSetting, smoothness);
}
bool CameraRotateSmoothingEnabled()
{
return GetRegistry(CameraRotateSmoothingSetting, true);
}
void SetCameraRotateSmoothingEnabled(const bool enabled)
{
SetRegistry(CameraRotateSmoothingSetting, enabled);
}
bool CameraTranslateSmoothingEnabled()
{
return GetRegistry(CameraTranslateSmoothingSetting, true);
}
void SetCameraTranslateSmoothingEnabled(const bool enabled)
{
SetRegistry(CameraTranslateSmoothingSetting, enabled);
}
AzFramework::InputChannelId CameraTranslateForwardChannelId()
{
return AzFramework::InputChannelId(
+6
View File
@@ -80,6 +80,12 @@ namespace SandboxEditor
SANDBOX_API float CameraTranslateSmoothness();
SANDBOX_API void SetCameraTranslateSmoothness(float smoothness);
SANDBOX_API bool CameraRotateSmoothingEnabled();
SANDBOX_API void SetCameraRotateSmoothingEnabled(bool enabled);
SANDBOX_API bool CameraTranslateSmoothingEnabled();
SANDBOX_API void SetCameraTranslateSmoothingEnabled(bool enabled);
SANDBOX_API AzFramework::InputChannelId CameraTranslateForwardChannelId();
SANDBOX_API void SetCameraTranslateForwardChannelId(AZStd::string_view cameraTranslateForwardId);
+29 -12
View File
@@ -132,12 +132,11 @@ namespace AZ::ViewportHelpers
{
static const char TextCantCreateCameraNoLevel[] = "Cannot create camera when no level is loaded.";
class EditorEntityNotifications
: public AzToolsFramework::EditorEntityContextNotificationBus::Handler
class EditorEntityNotifications : public AzToolsFramework::EditorEntityContextNotificationBus::Handler
{
public:
EditorEntityNotifications(EditorViewportWidget& renderViewport)
: m_renderViewport(renderViewport)
EditorEntityNotifications(EditorViewportWidget& editorViewportWidget)
: m_editorViewportWidget(editorViewportWidget)
{
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
}
@@ -147,22 +146,24 @@ namespace AZ::ViewportHelpers
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusDisconnect();
}
// AzToolsFramework::EditorEntityContextNotificationBus
// AzToolsFramework::EditorEntityContextNotificationBus overrides ...
void OnStartPlayInEditor() override
{
m_renderViewport.OnStartPlayInEditor();
m_editorViewportWidget.OnStartPlayInEditor();
}
void OnStopPlayInEditor() override
{
m_renderViewport.OnStopPlayInEditor();
m_editorViewportWidget.OnStopPlayInEditor();
}
void OnStartPlayInEditorBegin() override
{
m_renderViewport.OnStartPlayInEditorBegin();
m_editorViewportWidget.OnStartPlayInEditorBegin();
}
private:
EditorViewportWidget& m_renderViewport;
EditorViewportWidget& m_editorViewportWidget;
};
} // namespace AZ::ViewportHelpers
@@ -1027,10 +1028,16 @@ bool EditorViewportWidget::ShowingWorldSpace()
}
AZStd::shared_ptr<AtomToolsFramework::ModularViewportCameraController> CreateModularViewportCameraController(
AzFramework::ViewportId viewportId)
const AzFramework::ViewportId viewportId)
{
auto controller = AZStd::make_shared<AtomToolsFramework::ModularViewportCameraController>();
controller->SetCameraViewportContextBuilderCallback(
[viewportId](AZStd::unique_ptr<AtomToolsFramework::ModularCameraViewportContext>& cameraViewportContext)
{
cameraViewportContext = AZStd::make_unique<AtomToolsFramework::ModularCameraViewportContextImpl>(viewportId);
});
controller->SetCameraPriorityBuilderCallback(
[](AtomToolsFramework::CameraControllerPriorityFn& cameraControllerPriorityFn)
{
@@ -1049,6 +1056,16 @@ AZStd::shared_ptr<AtomToolsFramework::ModularViewportCameraController> CreateMod
{
return SandboxEditor::CameraTranslateSmoothness();
};
cameraProps.m_rotateSmoothingEnabledFn = []
{
return SandboxEditor::CameraRotateSmoothingEnabled();
};
cameraProps.m_translateSmoothingEnabledFn = []
{
return SandboxEditor::CameraTranslateSmoothingEnabled();
};
});
controller->SetCameraListBuilderCallback(
@@ -1950,7 +1967,7 @@ QPoint EditorViewportWidget::WorldToViewParticleEditor(const Vec3& wp, int width
Vec3 EditorViewportWidget::ViewToWorld(
const QPoint& vp, bool* collideWithTerrain, bool onlyTerrain, bool bSkipVegetation, bool bTestRenderMesh, bool* collideWithObject) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
AZ_UNUSED(collideWithTerrain)
AZ_UNUSED(onlyTerrain)
@@ -1985,7 +2002,7 @@ Vec3 EditorViewportWidget::ViewToWorldNormal(const QPoint& vp, bool onlyTerrain,
AZ_UNUSED(onlyTerrain)
AZ_UNUSED(bTestRenderMesh)
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
return Vec3(0, 0, 1);
}
+6 -1
View File
@@ -54,7 +54,8 @@ namespace AZ::ViewportHelpers
namespace AtomToolsFramework
{
class RenderViewportWidget;
}
class ModularViewportCameraController;
} // namespace AtomToolsFramework
namespace AzToolsFramework
{
@@ -389,3 +390,7 @@ private:
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
//! Creates a modular camera controller in the configuration used by the editor viewport.
SANDBOX_API AZStd::shared_ptr<AtomToolsFramework::ModularViewportCameraController> CreateModularViewportCameraController(
const AzFramework::ViewportId viewportId);
@@ -0,0 +1,170 @@
/*
* 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 <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
#include <AzToolsFramework/Input/QtEventToAzInputManager.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <EditorViewportWidget.h>
#include <Mocks/MockWindowRequests.h>
namespace UnitTest
{
const QSize WidgetSize = QSize(1920, 1080);
using AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
class ModularViewportCameraControllerFixture : public AllocatorsTestFixture
{
public:
static const AzFramework::ViewportId TestViewportId;
void SetUp() override
{
AllocatorsTestFixture::SetUp();
m_rootWidget = AZStd::make_unique<QWidget>();
m_rootWidget->setFixedSize(WidgetSize);
m_controllerList = AZStd::make_shared<AzFramework::ViewportControllerList>();
m_controllerList->RegisterViewportContext(TestViewportId);
m_inputChannelMapper = AZStd::make_unique<AzToolsFramework::QtEventToAzInputMapper>(m_rootWidget.get(), TestViewportId);
}
void TearDown()
{
m_inputChannelMapper.reset();
m_controllerList->UnregisterViewportContext(TestViewportId);
m_controllerList.reset();
m_rootWidget.reset();
AllocatorsTestFixture::TearDown();
}
AZStd::unique_ptr<QWidget> m_rootWidget;
AzFramework::ViewportControllerListPtr m_controllerList;
AZStd::unique_ptr<AzToolsFramework::QtEventToAzInputMapper> m_inputChannelMapper;
};
const AzFramework::ViewportId ModularViewportCameraControllerFixture::TestViewportId = AzFramework::ViewportId(0);
class TestModularCameraViewportContextImpl : public AtomToolsFramework::ModularCameraViewportContext
{
public:
AZ::Transform GetCameraTransform() const override
{
return m_cameraTransform;
}
void SetCameraTransform(const AZ::Transform& transform) override
{
m_cameraTransform = transform;
}
void ConnectViewMatrixChangedHandler(AZ::RPI::ViewportContext::MatrixChangedEvent::Handler&) override
{
// noop
}
private:
AZ::Transform m_cameraTransform = AZ::Transform::CreateIdentity();
};
TEST_F(ModularViewportCameraControllerFixture, Mouse_movement_does_not_accumulate_excessive_drift_in_modular_viewport_camera)
{
AzFramework::NativeWindowHandle nativeWindowHandle = nullptr;
const float deltaTime = 1.0f / 60.0f; // mimic 60fps
// Given
// listen for events signaled from QtEventToAzInputMapper and forward to the controller list
QObject::connect(
m_inputChannelMapper.get(), &AzToolsFramework::QtEventToAzInputMapper::InputChannelUpdated, m_rootWidget.get(),
[this, nativeWindowHandle](const AzFramework::InputChannel* inputChannel, [[maybe_unused]] QEvent* event)
{
m_controllerList->HandleInputChannelEvent(
AzFramework::ViewportControllerInputEvent{ TestViewportId, nativeWindowHandle, *inputChannel });
});
using ::testing::NiceMock;
using ::testing::Return;
NiceMock<MockWindowRequests> mockWindowRequests;
mockWindowRequests.Connect(nativeWindowHandle);
// note: WindowRequests is used internally by ModularViewportCameraController, this ensures it returns the viewport size we want
ON_CALL(mockWindowRequests, GetClientAreaSize())
.WillByDefault(Return(AzFramework::WindowSize(WidgetSize.width(), WidgetSize.height())));
// create editor modular camera
auto controller = CreateModularViewportCameraController(TestViewportId);
// set some overrides for the test
AtomToolsFramework::ModularCameraViewportContext* cameraViewportContextView = nullptr;
controller->SetCameraViewportContextBuilderCallback(
[&cameraViewportContextView](AZStd::unique_ptr<AtomToolsFramework::ModularCameraViewportContext>& cameraViewportContext)
{
cameraViewportContext = AZStd::make_unique<TestModularCameraViewportContextImpl>();
cameraViewportContextView = cameraViewportContext.get();
});
controller->SetCameraPropsBuilderCallback(
[](AzFramework::CameraProps& cameraProps)
{
cameraProps.m_rotateSmoothingEnabledFn = []
{
return false;
};
cameraProps.m_translateSmoothingEnabledFn = []
{
return false;
};
});
m_controllerList->Add(controller);
// move to the center of the screen
auto start = QPoint(WidgetSize.width() / 2, WidgetSize.height() / 2);
MouseMove(m_rootWidget.get(), start, QPoint(0, 0));
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
// When
// move mouse diagonally to top right, then to bottom left and back repeatedly
auto current = start;
auto halfDelta = QPoint(200, -200);
const int iterationsPerDiagonal = 50;
for (int diagonals = 0; diagonals < 80; ++diagonals)
{
for (int i = 0; i < iterationsPerDiagonal; ++i)
{
MousePressAndMove(m_rootWidget.get(), current, halfDelta / iterationsPerDiagonal, Qt::MouseButton::RightButton);
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
current += halfDelta / iterationsPerDiagonal;
}
if (diagonals % 2 == 0)
{
halfDelta.setX(halfDelta.x() * -1);
halfDelta.setY(halfDelta.y() * -1);
}
}
QTest::mouseRelease(m_rootWidget.get(), Qt::MouseButton::RightButton, Qt::KeyboardModifier::NoModifier, current);
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(deltaTime), AZ::ScriptTimePoint() });
// Then
// ensure the camera rotation is the identity (no significant drift has occurred as we moved the mouse)
const AZ::Transform cameraRotation = cameraViewportContextView->GetCameraTransform();
EXPECT_THAT(cameraRotation.GetRotation(), IsClose(AZ::Quaternion::CreateIdentity()));
mockWindowRequests.Disconnect();
}
} // namespace UnitTest
@@ -77,7 +77,7 @@ namespace UnitTest
class ViewportManipulatorControllerFixture : public AllocatorsTestFixture
{
public:
static const AzFramework::ViewportId TestViewportId = AzFramework::ViewportId(0);
static const AzFramework::ViewportId TestViewportId;
void SetUp() override
{
@@ -108,6 +108,8 @@ namespace UnitTest
AZStd::unique_ptr<AzToolsFramework::QtEventToAzInputMapper> m_inputChannelMapper;
};
const AzFramework::ViewportId ViewportManipulatorControllerFixture::TestViewportId = AzFramework::ViewportId(0);
TEST_F(ViewportManipulatorControllerFixture, An_event_is_not_propagated_to_the_viewport_when_a_manipulator_handles_it_first)
{
// forward input events to our controller list
+9 -11
View File
@@ -97,6 +97,7 @@ AZ_POP_DISABLE_WARNING
#include "ActionManager.h"
#include <ImGuiBus.h>
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
using namespace AZ;
using namespace AzQtComponents;
@@ -1474,25 +1475,22 @@ int MainWindow::ViewPaneVersion() const
void MainWindow::OnStopAllSounds()
{
Audio::SAudioRequest oStopAllSoundsRequest;
Audio::SAudioManagerRequestData<Audio::eAMRT_STOP_ALL_SOUNDS> oStopAllSoundsRequestData;
oStopAllSoundsRequest.pData = &oStopAllSoundsRequestData;
CryLogAlways("<Audio> Executed \"Stop All Sounds\" command.");
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequest, oStopAllSoundsRequest);
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalStopAllSounds);
}
void MainWindow::OnRefreshAudioSystem()
{
QString sLevelName = GetIEditor()->GetGameEngine()->GetLevelName();
AZStd::string levelName;
AzToolsFramework::EditorRequestBus::BroadcastResult(levelName, &AzToolsFramework::EditorRequestBus::Events::GetLevelName);
AZStd::to_lower(levelName.begin(), levelName.end());
if (QString::compare(sLevelName, "Untitled", Qt::CaseInsensitive) == 0)
if (levelName == "untitled")
{
// Rather pass nullptr to indicate that no level is loaded!
sLevelName = QString();
levelName.clear();
}
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::RefreshAudioSystem, sLevelName.toUtf8().data());
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(
&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalRefreshAudio, AZStd::string_view{ levelName });
}
void MainWindow::SaveLayout()
+1 -1
View File
@@ -274,7 +274,7 @@ Matrix34 CAxisGizmo::GetTransformation(RefCoordSys coordSys, IDisplayViewport* v
//////////////////////////////////////////////////////////////////////////
bool CAxisGizmo::MouseCallback(CViewport* view, EMouseEvent event, QPoint& point, [[maybe_unused]] int nFlags)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (event == eMouseLDown)
{
+3 -3
View File
@@ -1233,7 +1233,7 @@ float CBaseObject::GetCameraVisRatio(const CCamera& camera)
//////////////////////////////////////////////////////////////////////////
int CBaseObject::MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (event == eMouseMove || event == eMouseLDown)
{
@@ -1928,7 +1928,7 @@ bool CBaseObject::HitTestRectBounds(HitContext& hc, const AABB& box)
//////////////////////////////////////////////////////////////////////////
bool CBaseObject::HitTestRect(HitContext& hc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
AZ_PROFILE_FUNCTION(Entity);
AABB box;
@@ -1965,7 +1965,7 @@ bool CBaseObject::HitHelperTest(HitContext& hc)
//////////////////////////////////////////////////////////////////////////
bool CBaseObject::HitHelperAtTest(HitContext& hc, const Vec3& pos)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
AZ_PROFILE_FUNCTION(Entity);
bool bResult = false;
+1 -1
View File
@@ -497,7 +497,7 @@ bool CEntityObject::HitTestRect(HitContext& hc)
//////////////////////////////////////////////////////////////////////////
int CEntityObject::MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (event == eMouseMove || event == eMouseLDown)
{
+19 -19
View File
@@ -368,7 +368,7 @@ CBaseObject* CObjectManager::NewObject(const QString& typeName, CBaseObject* pre
//////////////////////////////////////////////////////////////////////////
void CObjectManager::DeleteObject(CBaseObject* obj)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (m_currEditObject == obj)
{
EndEditParams();
@@ -414,7 +414,7 @@ void CObjectManager::DeleteObject(CBaseObject* obj)
//////////////////////////////////////////////////////////////////////////
void CObjectManager::DeleteSelection(CSelectionGroup* pSelection)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (pSelection == nullptr)
{
return;
@@ -478,7 +478,7 @@ void CObjectManager::DeleteSelection(CSelectionGroup* pSelection)
//////////////////////////////////////////////////////////////////////////
void CObjectManager::DeleteAllObjects()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
EndEditParams();
@@ -519,7 +519,7 @@ void CObjectManager::DeleteAllObjects()
CBaseObject* CObjectManager::CloneObject(CBaseObject* obj)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
assert(obj);
//CRuntimeClass *cls = obj->GetRuntimeClass();
//CBaseObject *clone = (CBaseObject*)cls->CreateObject();
@@ -1112,7 +1112,7 @@ void CObjectManager::SerializeNameSelection(XmlNodeRef& rootNode, bool bLoading)
//////////////////////////////////////////////////////////////////////////
int CObjectManager::ClearSelection()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Make sure to unlock selection.
GetIEditor()->LockSelection(false);
@@ -1165,7 +1165,7 @@ int CObjectManager::ClearSelection()
//////////////////////////////////////////////////////////////////////////
int CObjectManager::InvertSelection()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
int selCount = 0;
// iterate all objects.
@@ -1189,7 +1189,7 @@ int CObjectManager::InvertSelection()
void CObjectManager::SetSelection(const QString& name)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
CSelectionGroup* selection = stl::find_in_map(m_selections, name, (CSelectionGroup*)nullptr);
if (selection)
{
@@ -1202,7 +1202,7 @@ void CObjectManager::SetSelection(const QString& name)
void CObjectManager::RemoveSelection(const QString& name)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
QString selName = name;
CSelectionGroup* selection = stl::find_in_map(m_selections, name, (CSelectionGroup*)nullptr);
@@ -1221,7 +1221,7 @@ void CObjectManager::RemoveSelection(const QString& name)
void CObjectManager::SelectCurrent()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
for (int i = 0; i < m_currSelection->GetCount(); i++)
{
CBaseObject* obj = m_currSelection->GetObject(i);
@@ -1236,7 +1236,7 @@ void CObjectManager::SelectCurrent()
void CObjectManager::UnselectCurrent()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Make sure to unlock selection.
GetIEditor()->LockSelection(false);
@@ -1260,7 +1260,7 @@ void CObjectManager::UnselectCurrent()
//////////////////////////////////////////////////////////////////////////
void CObjectManager::Display(DisplayContext& dc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
int currentHideMask = GetIEditor()->GetDisplaySettings()->GetObjectHideMask();
if (m_lastHideMask != currentHideMask)
@@ -1320,7 +1320,7 @@ void CObjectManager::FindDisplayableObjects(DisplayContext& dc, [[maybe_unused]]
return;
}
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
auto start = std::chrono::steady_clock::now();
CBaseObjectsCache* pDispayedViewObjects = dc.view->GetVisibleObjectsCache();
@@ -1451,7 +1451,7 @@ void CObjectManager::EndEditParams([[maybe_unused]] int flags)
//! Select objects within specified distance from given position.
int CObjectManager::SelectObjects(const AABB& box, bool bUnselect)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
int numSel = 0;
AABB objBounds;
@@ -1551,7 +1551,7 @@ bool CObjectManager::IsObjectDeletionAllowed(CBaseObject* pObject)
//////////////////////////////////////////////////////////////////////////
void CObjectManager::DeleteSelection()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Make sure to unlock selection.
GetIEditor()->LockSelection(false);
@@ -1581,7 +1581,7 @@ void CObjectManager::DeleteSelection()
//////////////////////////////////////////////////////////////////////////
bool CObjectManager::HitTestObject(CBaseObject* obj, HitContext& hc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (obj->IsFrozen())
{
@@ -1648,7 +1648,7 @@ bool CObjectManager::HitTestObject(CBaseObject* obj, HitContext& hc)
//////////////////////////////////////////////////////////////////////////
bool CObjectManager::HitTest(HitContext& hitInfo)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
hitInfo.object = nullptr;
hitInfo.dist = FLT_MAX;
@@ -1766,7 +1766,7 @@ bool CObjectManager::HitTest(HitContext& hitInfo)
}
void CObjectManager::FindObjectsInRect(CViewport* view, const QRect& rect, std::vector<GUID>& guids)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (rect.width() < 1 || rect.height() < 1)
{
@@ -1795,7 +1795,7 @@ void CObjectManager::FindObjectsInRect(CViewport* view, const QRect& rect, std::
//////////////////////////////////////////////////////////////////////////
void CObjectManager::SelectObjectsInRect(CViewport* view, const QRect& rect, bool bSelect)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Ignore too small rectangles.
if (rect.width() < 1 || rect.height() < 1)
@@ -2363,7 +2363,7 @@ bool CObjectManager::ConvertToType(CBaseObject* pObject, const QString& typeName
//////////////////////////////////////////////////////////////////////////
void CObjectManager::SetObjectSelected(CBaseObject* pObject, bool bSelect)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Only select/unselect once.
if ((pObject->IsSelected() && bSelect) || (!pObject->IsSelected() && !bSelect))
{
@@ -204,7 +204,7 @@ CUndoBaseObjectBulkSelect::CUndoBaseObjectBulkSelect(const AZStd::unordered_set<
void CUndoBaseObjectBulkSelect::Undo(bool bUndo)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (!bUndo)
{
return;
@@ -217,7 +217,7 @@ void CUndoBaseObjectBulkSelect::Undo(bool bUndo)
void CUndoBaseObjectBulkSelect::Redo()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
&AzToolsFramework::ToolsApplicationRequests::MarkEntitiesSelected,
@@ -256,7 +256,7 @@ CUndoBaseObjectClearSelection::CUndoBaseObjectClearSelection(const CSelectionGro
void CUndoBaseObjectClearSelection::Undo(bool bUndo)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (!bUndo)
{
@@ -270,7 +270,7 @@ void CUndoBaseObjectClearSelection::Undo(bool bUndo)
void CUndoBaseObjectClearSelection::Redo()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
AzToolsFramework::ToolsApplicationRequestBus::Broadcast(
&AzToolsFramework::ToolsApplicationRequests::SetSelectedEntities,
@@ -679,7 +679,7 @@ bool CComponentEntityObject::HitHelperTest(HitContext& hc)
bool CComponentEntityObject::HitTest(HitContext& hc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
AZ_PROFILE_FUNCTION(Entity);
if (m_iconOnlyHitTest)
{
@@ -705,7 +705,7 @@ bool CComponentEntityObject::HitTest(HitContext& hc)
[&hc, &closestDistance, &rayIntersection, &preciseSelectionRequired, viewportId](
AzToolsFramework::EditorComponentSelectionRequests* handler) -> bool
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
AZ_PROFILE_FUNCTION(Entity);
if (handler->SupportsEditorRayIntersect())
{
@@ -768,7 +768,7 @@ bool CComponentEntityObject::HitTest(HitContext& hc)
void CComponentEntityObject::GetBoundBox(AABB& box)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Entity);
AZ_PROFILE_FUNCTION(Entity);
box.Reset();
@@ -472,7 +472,7 @@ void SandboxIntegrationManager::EntityParentChanged(
const AZ::EntityId newParentId,
const AZ::EntityId oldParentId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
if (m_unsavedEntities.find(entityId) != m_unsavedEntities.end())
{
@@ -646,16 +646,27 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con
QAction* action = nullptr;
action = menu->addAction(QObject::tr("Create entity"));
QObject::connect(action, &QAction::triggered, action, [this] { ContextMenu_NewEntity(); });
if (selected.size() == 1)
// when nothing is selected, entity is created at root level
if (selected.size() == 0)
{
action = menu->addAction(QObject::tr("Create child entity"));
QObject::connect(action, &QAction::triggered, action, [selected]
{
EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, CreateNewEntityAsChild, selected.front());
});
action = menu->addAction(QObject::tr("Create entity"));
QObject::connect(
action, &QAction::triggered, action,
[this]
{
ContextMenu_NewEntity();
});
}
// when a single entity is selected, entity is created as its child
else if (selected.size() == 1)
{
action = menu->addAction(QObject::tr("Create entity"));
QObject::connect(
action, &QAction::triggered, action,
[selected]
{
EBUS_EVENT(AzToolsFramework::EditorRequests::Bus, CreateNewEntityAsChild, selected.front());
});
}
bool prefabSystemEnabled = false;
@@ -847,7 +858,7 @@ void SandboxIntegrationManager::SetupLayerContextMenu(QMenu* menu)
void SandboxIntegrationManager::SetupSliceContextMenu(QMenu* menu)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
AzToolsFramework::EntityIdList selectedEntities;
GetSelectedOrHighlightedEntities(selectedEntities);
@@ -949,7 +960,7 @@ void SandboxIntegrationManager::SetupSliceContextMenu(QMenu* menu)
void SandboxIntegrationManager::SetupSliceContextMenu_Modify(QMenu* menu, const AzToolsFramework::EntityIdList& selectedEntities, [[maybe_unused]] const AZ::u32 numEntitiesInSlices)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
using namespace AzToolsFramework;
// Gather the set of relevant entities from the selected entities and all descendants
@@ -1072,7 +1083,7 @@ void SandboxIntegrationManager::CreateEditorRepresentation(AZ::Entity* entity)
bool SandboxIntegrationManager::DestroyEditorRepresentation(AZ::EntityId entityId, bool deleteAZEntity)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
IEditor* editor = GetIEditor();
if (editor->GetObjectManager())
@@ -1084,7 +1095,7 @@ bool SandboxIntegrationManager::DestroyEditorRepresentation(AZ::EntityId entityI
{
static_cast<CComponentEntityObject*>(object)->AssignEntity(nullptr, deleteAZEntity);
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "SandboxIntegrationManager::DestroyEditorRepresentation:ObjManagerDeleteObject");
AZ_PROFILE_SCOPE(AzToolsFramework, "SandboxIntegrationManager::DestroyEditorRepresentation:ObjManagerDeleteObject");
editor->GetObjectManager()->DeleteObject(object);
}
return true;
@@ -1206,7 +1217,7 @@ void SandboxIntegrationManager::ClearRedoStack()
void SandboxIntegrationManager::CloneSelection(bool& handled)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AzToolsFramework::EntityIdList entities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(
@@ -1839,7 +1850,7 @@ AZStd::string SandboxIntegrationManager::GetComponentEditorIcon(const AZ::Uuid&
AZStd::string SandboxIntegrationManager::GetComponentIconPath(const AZ::Uuid& componentType,
AZ::Crc32 componentIconAttrib, AZ::Component* component)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
if (componentIconAttrib != AZ::Edit::Attributes::Icon
&& componentIconAttrib != AZ::Edit::Attributes::ViewportIcon
&& componentIconAttrib != AZ::Edit::Attributes::HideIcon)
@@ -1054,7 +1054,7 @@ bool OutlinerListModel::dropMimeDataEntities(const QMimeData* data, Qt::DropActi
bool OutlinerListModel::CanReparentEntities(const AZ::EntityId& newParentId, const AzToolsFramework::EntityIdList &selectedEntityIds) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
if (selectedEntityIds.empty())
{
return false;
@@ -1143,7 +1143,7 @@ bool OutlinerListModel::CanReparentEntities(const AZ::EntityId& newParentId, con
bool OutlinerListModel::ReparentEntities(const AZ::EntityId& newParentId, const AzToolsFramework::EntityIdList &selectedEntityIds, const AZ::EntityId& beforeEntityId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
if (!CanReparentEntities(newParentId, selectedEntityIds))
{
return false;
@@ -1233,7 +1233,7 @@ bool OutlinerListModel::ReparentEntities(const AZ::EntityId& newParentId, const
QMimeData* OutlinerListModel::mimeData(const QModelIndexList& indexes) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AZ::TypeId uuid1 = AZ::AzTypeInfo<AZ::Entity>::Uuid();
AZ::TypeId uuid2 = AZ::AzTypeInfo<AzToolsFramework::EditorEntityIdContainer>::Uuid();
@@ -1323,7 +1323,7 @@ public:
void OutlinerListModel::ProcessEntityUpdates()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
m_entityChangeQueued = false;
if (m_layoutResetQueued)
{
@@ -1331,7 +1331,7 @@ void OutlinerListModel::ProcessEntityUpdates()
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Editor, "OutlinerListModel::ProcessEntityUpdates:ExpandQueue");
AZ_PROFILE_SCOPE(Editor, "OutlinerListModel::ProcessEntityUpdates:ExpandQueue");
for (auto entityId : m_entityExpandQueue)
{
emit ExpandEntity(entityId, IsExpanded(entityId));
@@ -1340,7 +1340,7 @@ void OutlinerListModel::ProcessEntityUpdates()
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Editor, "OutlinerListModel::ProcessEntityUpdates:SelectQueue");
AZ_PROFILE_SCOPE(Editor, "OutlinerListModel::ProcessEntityUpdates:SelectQueue");
for (auto entityId : m_entitySelectQueue)
{
emit SelectEntity(entityId, AzToolsFramework::IsSelected(entityId));
@@ -1350,7 +1350,7 @@ void OutlinerListModel::ProcessEntityUpdates()
if (!m_entityChangeQueue.empty())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Editor, "OutlinerListModel::ProcessEntityUpdates:ChangeQueue");
AZ_PROFILE_SCOPE(Editor, "OutlinerListModel::ProcessEntityUpdates:ChangeQueue");
// its faster to just do a bulk data change than to carefully pick out indices
// so we'll just merge all ranges into a single range rather than try to make gaps
@@ -1383,7 +1383,7 @@ void OutlinerListModel::ProcessEntityUpdates()
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Editor, "OutlinerListModel::ProcessEntityUpdates:LayoutChanged");
AZ_PROFILE_SCOPE(Editor, "OutlinerListModel::ProcessEntityUpdates:LayoutChanged");
if (m_entityLayoutQueued)
{
emit layoutAboutToBeChanged();
@@ -1393,7 +1393,7 @@ void OutlinerListModel::ProcessEntityUpdates()
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Editor, "OutlinerListModel::ProcessEntityUpdates:InvalidateFilter");
AZ_PROFILE_SCOPE(Editor, "OutlinerListModel::ProcessEntityUpdates:InvalidateFilter");
if (m_isFilterDirty)
{
InvalidateFilter();
@@ -1416,7 +1416,7 @@ void OutlinerListModel::OnEntityInfoResetEnd()
void OutlinerListModel::ProcessEntityInfoResetEnd()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
m_layoutResetQueued = false;
m_entityChangeQueued = false;
m_entityChangeQueue.clear();
@@ -1437,7 +1437,7 @@ void OutlinerListModel::OnEntityInfoUpdatedAddChildBegin(AZ::EntityId parentId,
void OutlinerListModel::OnEntityInfoUpdatedAddChildEnd(AZ::EntityId parentId, AZ::EntityId childId)
{
(void)parentId;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
endInsertRows();
//expand ancestors if a new descendant is already selected
@@ -1475,7 +1475,7 @@ void OutlinerListModel::OnEntityInfoUpdatedRemoveChildBegin(AZ::EntityId parentI
void OutlinerListModel::OnEntityInfoUpdatedRemoveChildEnd(AZ::EntityId parentId, AZ::EntityId childId)
{
(void)childId;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
endResetModel();
@@ -1494,7 +1494,7 @@ void OutlinerListModel::OnEntityInfoUpdatedOrderBegin(AZ::EntityId parentId, AZ:
void OutlinerListModel::OnEntityInfoUpdatedOrderEnd(AZ::EntityId parentId, AZ::EntityId childId, AZ::u64 index)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
(void)index;
m_entityLayoutQueued = true;
QueueEntityUpdate(parentId);
@@ -1565,7 +1565,7 @@ QString OutlinerListModel::GetSliceAssetName(const AZ::EntityId& entityId) const
QModelIndex OutlinerListModel::GetIndexFromEntity(const AZ::EntityId& entityId, int column) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
if (entityId.IsValid())
{
@@ -1727,7 +1727,7 @@ void OutlinerListModel::OnEditorEntityDuplicated(const AZ::EntityId& oldEntity,
void OutlinerListModel::ExpandAncestors(const AZ::EntityId& entityId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
//typically to reveal selected entities, expand all parent entities
if (entityId.IsValid())
{
@@ -1932,7 +1932,7 @@ bool OutlinerListModel::HasSelectedDescendant(const AZ::EntityId& entityId) cons
bool OutlinerListModel::AreAllDescendantsSameLockState(const AZ::EntityId& entityId) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
//TODO result can be cached in mutable map and cleared when any descendant changes to avoid recursion in deep hierarchies
bool isLocked = false;
AzToolsFramework::EditorEntityInfoRequestBus::EventResult(isLocked, entityId, &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsJustThisEntityLocked);
@@ -1953,7 +1953,7 @@ bool OutlinerListModel::AreAllDescendantsSameLockState(const AZ::EntityId& entit
bool OutlinerListModel::AreAllDescendantsSameVisibleState(const AZ::EntityId& entityId) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
//TODO result can be cached in mutable map and cleared when any descendant changes to avoid recursion in deep hierarchies
bool isVisible = AzToolsFramework::IsEntitySetToBeVisible(entityId);
@@ -96,7 +96,7 @@ namespace
void SortEntityChildren(AZ::EntityId entityId, const EntityIdCompareFunc& comparer, AzToolsFramework::EntityOrderArray* newEntityOrder = nullptr)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AzToolsFramework::EntityOrderArray entityOrderArray = AzToolsFramework::GetEntityChildOrder(entityId);
AZStd::sort(entityOrderArray.begin(), entityOrderArray.end(), comparer);
@@ -110,7 +110,7 @@ namespace
void SortEntityChildrenRecursively(AZ::EntityId entityId, const EntityIdCompareFunc& comparer)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AzToolsFramework::EntityOrderArray entityOrderArray;
SortEntityChildren(entityId, comparer, &entityOrderArray);
@@ -303,7 +303,7 @@ void OutlinerWidget::OnSelectionChanged(const QItemSelection& selected, const QI
return;
}
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AzToolsFramework::EntityIdList newlySelected;
ExtractEntityIdsFromSelection(selected, newlySelected);
@@ -450,7 +450,7 @@ void OutlinerWidget::UpdateSelection()
{
if (m_selectionChangeQueued)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
m_selectionChangeInProgress = true;
@@ -458,7 +458,7 @@ void OutlinerWidget::UpdateSelection()
{
// Calling Deselect for a large number of items is very slow,
// use a single ClearAndSelect call instead.
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:ClearAndSelect");
AZ_PROFILE_SCOPE(AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:ClearAndSelect");
AzToolsFramework::EntityIdList selectedEntities;
AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult(selectedEntities, &AzToolsFramework::ToolsApplicationRequests::Bus::Events::GetSelectedEntities);
@@ -469,12 +469,12 @@ void OutlinerWidget::UpdateSelection()
else
{
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:Deselect");
AZ_PROFILE_SCOPE(AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:Deselect");
m_gui->m_objectTree->selectionModel()->select(
BuildSelectionFromEntities(m_entitiesToDeselect), QItemSelectionModel::Deselect);
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:Select");
AZ_PROFILE_SCOPE(AzToolsFramework, "OutlinerWidget::ModelEntitySelectionChanged:Select");
m_gui->m_objectTree->selectionModel()->select(
BuildSelectionFromEntities(m_entitiesToSelect), QItemSelectionModel::Select);
}
@@ -497,7 +497,7 @@ void OutlinerWidget::UpdateSelection()
template <class EntityIdCollection>
QItemSelection OutlinerWidget::BuildSelectionFromEntities(const EntityIdCollection& entityIds)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
QItemSelection selection;
for (const auto& entityId : entityIds)
@@ -517,7 +517,7 @@ QItemSelection OutlinerWidget::BuildSelectionFromEntities(const EntityIdCollecti
void OutlinerWidget::contextMenuEvent(QContextMenuEvent* event)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
bool isDocumentOpen = false;
EBUS_EVENT_RESULT(isDocumentOpen, AzToolsFramework::EditorRequests::Bus, IsLevelDocumentOpen);
@@ -1272,7 +1272,7 @@ void OutlinerWidget::ExtractEntityIdsFromSelection(const QItemSelection& selecti
void OutlinerWidget::OnSearchTextChanged(const QString& activeTextFilter)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
AZStd::string filterString = activeTextFilter.toUtf8().data();
m_listModel->SearchStringChanged(filterString);
@@ -1388,7 +1388,7 @@ void OutlinerWidget::QueueContentUpdateSort(const AZ::EntityId& entityId)
void OutlinerWidget::SortContent()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
m_sortContentQueued = false;
@@ -1424,7 +1424,7 @@ void OutlinerWidget::OnSortModeChanged(EntityOutliner::DisplaySortMode sortMode)
if (sortMode != EntityOutliner::DisplaySortMode::Manually)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
AZ_PROFILE_FUNCTION(AzToolsFramework);
auto comparer = AZStd::bind(&CompareEntitiesForSorting, AZStd::placeholders::_1, AZStd::placeholders::_2, sortMode);
SortEntityChildrenRecursively(AZ::EntityId(), comparer);
}
@@ -43,7 +43,7 @@ AssetImporterDocument::AssetImporterDocument()
bool AssetImporterDocument::LoadScene(const AZStd::string& sceneFullPath)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
namespace SceneEvents = AZ::SceneAPI::Events;
SceneEvents::SceneSerializationBus::BroadcastResult(m_scene, &SceneEvents::SceneSerializationBus::Events::LoadScene, sceneFullPath, AZ::Uuid::CreateNull());
return !!m_scene;
@@ -45,7 +45,7 @@ AZ::SceneAPI::UI::ManifestWidget* ImporterRootDisplay::GetManifestWidget()
void ImporterRootDisplay::SetSceneDisplay(const QString& headerText, const AZStd::shared_ptr<AZ::SceneAPI::Containers::Scene>& scene)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (!scene)
{
AZ_Assert(scene, "No scene provided to display.");
@@ -62,7 +62,7 @@ void ImporterRootDisplay::SetSceneDisplay(const QString& headerText, const AZStd
void ImporterRootDisplay::HandleSceneWasReset(const AZStd::shared_ptr<AZ::SceneAPI::Containers::Scene>& scene)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Don't accept updates while the widget is being filled in.
BusDisconnect();
m_manifestWidget->BuildFromScene(scene);
@@ -6,6 +6,7 @@
*
*/
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/string/conversions.h>
@@ -37,7 +38,7 @@ namespace AZ
AZStd::shared_ptr<SceneAPI::Containers::Scene> SceneSerializationHandler::LoadScene(
const AZStd::string& filePath, Uuid sceneSourceGuid)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
namespace Utilities = AZ::SceneAPI::Utilities;
using AZ::SceneAPI::Events::AssetImportRequest;
+2 -2
View File
@@ -969,7 +969,7 @@ void QtViewport::MakeConstructionPlane(int axis)
//////////////////////////////////////////////////////////////////////////
Vec3 QtViewport::MapViewToCP(const QPoint& point, int axis)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
if (axis == AXIS_TERRAIN)
{
@@ -1336,7 +1336,7 @@ bool QtViewport::GetAdvancedSelectModeFlag()
//////////////////////////////////////////////////////////////////////////
bool QtViewport::MouseCallback(EMouseEvent event, const QPoint& point, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor);
AZ_PROFILE_FUNCTION(Editor);
// Ignore any mouse events in game mode.
if (GetIEditor()->IsInGameMode())
+27 -14
View File
@@ -43,6 +43,8 @@
#include <AzCore/Casting/numeric_cast.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
#include "ui_ViewportTitleDlg.h"
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
@@ -119,17 +121,20 @@ CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent)
LoadCustomPresets("AspectRatioPresets", "AspectRatioPreset", m_customAspectRatioPresets);
LoadCustomPresets("ResPresets", "ResPreset", m_customResPresets);
// audio request setup
m_oMuteAudioRequest.pData = &m_oMuteAudioRequestData;
m_oUnmuteAudioRequest.pData = &m_oUnmuteAudioRequestData;
SetupCameraDropdownMenu();
SetupResolutionDropdownMenu();
SetupViewportInformationMenu();
SetupHelpersButton();
SetupOverflowMenu();
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequest, gSettings.bMuteAudio ? m_oMuteAudioRequest : m_oUnmuteAudioRequest);
if (gSettings.bMuteAudio)
{
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalMuteAudio);
}
else
{
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalUnmuteAudio);
}
connect(this, &CViewportTitleDlg::ActionTriggered, MainWindow::instance()->GetActionManager(), &ActionManager::ActionTriggered);
@@ -877,25 +882,33 @@ void CViewportTitleDlg::OnBnClickedGotoPosition()
void CViewportTitleDlg::OnBnClickedMuteAudio()
{
gSettings.bMuteAudio = !gSettings.bMuteAudio;
Audio::AudioSystemRequestBus::Broadcast(
&Audio::AudioSystemRequestBus::Events::PushRequest, gSettings.bMuteAudio ? m_oMuteAudioRequest : m_oUnmuteAudioRequest);
if (gSettings.bMuteAudio)
{
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalMuteAudio);
}
else
{
LmbrCentral::AudioSystemComponentRequestBus::Broadcast(&LmbrCentral::AudioSystemComponentRequestBus::Events::GlobalUnmuteAudio);
}
UpdateMuteActionText();
}
void CViewportTitleDlg::UpdateMuteActionText()
{
if (!Audio::AudioSystemRequestBus::HasHandlers())
{
m_audioMuteAction->setEnabled(false);
m_audioMuteAction->setText(tr("Mute Audio: Enable Audio Gem"));
}
else
bool audioSystemConnected = false;
LmbrCentral::AudioSystemComponentRequestBus::BroadcastResult(
audioSystemConnected, &LmbrCentral::AudioSystemComponentRequestBus::Events::IsAudioSystemInitialized);
if (audioSystemConnected)
{
m_audioMuteAction->setEnabled(true);
m_audioMuteAction->setText(gSettings.bMuteAudio ? tr("Un-mute Audio") : tr("Mute Audio"));
}
else
{
m_audioMuteAction->setEnabled(false);
m_audioMuteAction->setText(tr("Mute Audio: Enable Audio Gem"));
}
}
void CViewportTitleDlg::OnHMDInitialized()
-8
View File
@@ -14,8 +14,6 @@
#if !defined(Q_MOC_RUN)
#include <AzCore/Component/Component.h>
#include <IAudioSystem.h>
#include <functional>
#include <QSharedPointer>
#include <QWidgetAction>
@@ -178,12 +176,6 @@ protected:
QWidgetAction* m_gridSizeActionWidget = nullptr;
QWidgetAction* m_angleSizeActionWidget = nullptr;
Audio::SAudioRequest m_oMuteAudioRequest;
Audio::SAudioManagerRequestData<Audio::eAMRT_MUTE_ALL> m_oMuteAudioRequestData;
Audio::SAudioRequest m_oUnmuteAudioRequest;
Audio::SAudioManagerRequestData<Audio::eAMRT_UNMUTE_ALL> m_oUnmuteAudioRequestData;
QScopedPointer<Ui::ViewportTitleDlg> m_ui;
};
+1
View File
@@ -21,6 +21,7 @@ set(FILES
Lib/Tests/test_ViewportTitleDlgPythonBindings.cpp
Lib/Tests/test_DisplaySettingsPythonBindings.cpp
Lib/Tests/test_ViewportManipulatorController.cpp
Lib/Tests/test_ModularViewportCameraController.cpp
DisplaySettingsPythonFuncs.cpp
DisplaySettingsPythonFuncs.h
)
@@ -26,8 +26,8 @@
#if AZ_ENABLED_VERBOSE_ANDROID_IO_PROFILING
#include <AzCore/Debug/Profiler.h>
#define ANDROID_IO_PROFILE_SECTION AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore)
#define ANDROID_IO_PROFILE_SECTION_ARGS(...) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, __VA_ARGS__)
#define ANDROID_IO_PROFILE_SECTION AZ_PROFILE_FUNCTION(AzCore)
#define ANDROID_IO_PROFILE_SECTION_ARGS(...) AZ_PROFILE_SCOPE(AzCore, __VA_ARGS__)
#else
#define ANDROID_IO_PROFILE_SECTION
#define ANDROID_IO_PROFILE_SECTION_ARGS(...)
@@ -27,7 +27,7 @@ namespace AZ::Data
void AssetDataStream::Open(const AZStd::vector<AZ::u8>& data)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(!m_isOpen, "Attempting to open the stream when it is already open.");
@@ -45,7 +45,7 @@ namespace AZ::Data
void AssetDataStream::Open(AZStd::vector<AZ::u8>&& data)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(!m_isOpen, "Attempting to open the stream when it is already open.");
@@ -62,7 +62,7 @@ namespace AZ::Data
AZStd::chrono::milliseconds deadline, AZ::IO::IStreamerTypes::Priority priority,
OnCompleteCallback loadCallback)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(!m_isOpen, "Attempting to open the stream when it is already open.");
AZ_Assert(!m_curReadRequest, "Queueing an asset stream load while one is still in progress.");
@@ -80,7 +80,7 @@ namespace AZ::Data
// Set up the callback that will process the asset data once the raw file load is finished.
auto streamerCallback = [this, loadCallback](AZ::IO::FileRequestHandle fileHandle)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "AZ::Data::LoadAssetDataStreamCallback %s",
AZ_PROFILE_SCOPE(AzCore, "AZ::Data::LoadAssetDataStreamCallback %s",
m_filePath.c_str());
// Get the results
@@ -183,13 +183,13 @@ namespace AZ::Data
// the real interval we want to record below won't show up unless this is here.
/**/
{
AZ_PROFILE_INTERVAL_START(AZ::Debug::ProfileCategory::AzCore, this + 1, "AssetDataStream: %s", streamName);
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::AzCore, this + 1);
AZ_PROFILE_INTERVAL_START(AzCore, this + 1, "AssetDataStream: %s", streamName);
AZ_PROFILE_INTERVAL_END(AzCore, this + 1);
}
/**/
// Start a timespan marker to track the full load time for the requested asset.
AZ_PROFILE_INTERVAL_START(AZ::Debug::ProfileCategory::AzCore, this, "AssetLoad: %s", streamName);
AZ_PROFILE_INTERVAL_START(AzCore, this, "AssetLoad: %s", streamName);
// Lock the allocator to ensure it remains active from Open to Close.
m_bufferAllocator->LockAllocator();
@@ -216,7 +216,7 @@ namespace AZ::Data
ClearInternalStateData();
// End the load time timespan marker for this asset.
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::AzCore, this);
AZ_PROFILE_INTERVAL_END(AzCore, this);
}
void AssetDataStream::RequestCancel()
@@ -231,7 +231,7 @@ namespace AZ::Data
void AssetDataStream::Seek(AZ::IO::OffsetType bytes, AZ::IO::GenericStream::SeekMode mode)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ::IO::OffsetType requestedOffset = 0;
switch (mode)
@@ -261,7 +261,7 @@ namespace AZ::Data
AZ::IO::SizeType AssetDataStream::Read(AZ::IO::SizeType bytes, void* oBuffer)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (m_curOffset >= m_loadedSize)
{
return 0;
@@ -163,7 +163,7 @@ namespace AZ
else
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "AZ::Data::LoadAssetJob::Process: %s",
AZ_PROFILE_SCOPE(AzCore, "AZ::Data::LoadAssetJob::Process: %s",
asset.GetHint().c_str());
AZ_ASSET_ATTACH_TO_SCOPE(this);
@@ -198,7 +198,7 @@ namespace AZ
if(cl_assetLoadDelay > 0)
{
AZ_PROFILE_SCOPE_IDLE(AZ::Debug::ProfileCategory::AzCore, "LoadData suspended");
AZ_PROFILE_SCOPE(AzCore, "LoadData suspended");
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(cl_assetLoadDelay));
}
@@ -314,7 +314,7 @@ namespace AZ
protected:
void Wait()
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "WaitForAsset - %s", m_assetData.GetHint().c_str());
AZ_PROFILE_SCOPE(AzCore, "WaitForAsset - %s", m_assetData.GetHint().c_str());
// Continue to loop until the load completes. (Most of the time in the loop will be spent in a thread-blocking state)
while (!m_loadCompleted)
@@ -344,7 +344,7 @@ namespace AZ
void Finish()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
m_loadCompleted = true;
m_waitEvent.release();
}
@@ -403,7 +403,7 @@ namespace AZ
void SaveAsset()
{
auto asset = m_asset.GetStrongReference();
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
bool isSaved = false;
AssetStreamInfo saveInfo = m_owner->GetSaveStreamInfoForAsset(asset.GetId(), asset.GetType());
if (saveInfo.IsValid())
@@ -565,7 +565,7 @@ namespace AZ
//=========================================================================
void AssetManager::DispatchEvents()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AssetManagerNotificationBus::Broadcast(&AssetManagerNotificationBus::Events::OnAssetEventsDispatchBegin);
AssetBus::ExecuteQueuedEvents();
AssetManagerNotificationBus::Broadcast(&AssetManagerNotificationBus::Events::OnAssetEventsDispatchEnd);
@@ -937,14 +937,14 @@ namespace AZ
Asset<AssetData> AssetManager::GetAssetInternal(const AssetId& assetId, [[maybe_unused]] const AssetType& assetType,
AssetLoadBehavior assetReferenceLoadBehavior, const AssetLoadParameters& loadParams, AssetInfo assetInfo /*= () */, bool signalLoaded /*= false */)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Error("AssetDatabase", assetId.IsValid(), "GetAsset called with invalid asset Id.");
AZ_Error("AssetDatabase", !assetType.IsNull(), "GetAsset called with invalid asset type.");
bool assetMissing = false;
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "GetAsset: GetAssetInfo");
AZ_PROFILE_SCOPE(AzCore, "GetAsset: GetAssetInfo");
// Attempt to look up asset info from catalog
// This is so that when assetId is a legacy id, we're operating on the canonical id anyway
@@ -974,7 +974,7 @@ namespace AZ
}
}
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "GetAsset: %s", assetInfo.m_relativePath.c_str());
AZ_PROFILE_SCOPE(AzCore, "GetAsset: %s", assetInfo.m_relativePath.c_str());
AZ_ASSET_NAMED_SCOPE("GetAsset: %s", assetInfo.m_relativePath.c_str());
AZStd::shared_ptr<AssetDataStream> dataStream;
@@ -992,7 +992,7 @@ namespace AZ
// check if asset already exists
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "GetAsset: FindAsset");
AZ_PROFILE_SCOPE(AzCore, "GetAsset: FindAsset");
AssetMap::iterator it = m_assets.find(assetInfo.m_assetId);
if (it != m_assets.end())
@@ -1007,7 +1007,7 @@ namespace AZ
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "GetAsset: FindAssetHandler");
AZ_PROFILE_SCOPE(AzCore, "GetAsset: FindAssetHandler");
// find the asset type handler
AssetHandlerMap::iterator handlerIt = m_handlers.find(assetInfo.m_assetType);
@@ -1019,7 +1019,7 @@ namespace AZ
handler = handlerIt->second;
if (isNewEntry)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "GetAsset: CreateAsset");
AZ_PROFILE_SCOPE(AzCore, "GetAsset: CreateAsset");
assetData = handler->CreateAsset(assetInfo.m_assetId, assetInfo.m_assetType);
if (assetData)
@@ -1043,7 +1043,7 @@ namespace AZ
{
if (isNewEntry && assetData->IsRegisterReadonlyAndShareable())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "GetAsset: RegisterAsset");
AZ_PROFILE_SCOPE(AzCore, "GetAsset: RegisterAsset");
m_assets.insert(AZStd::make_pair(assetInfo.m_assetId, assetData));
}
if (assetData->GetStatus() == AssetData::AssetStatus::NotLoaded)
@@ -1596,7 +1596,7 @@ namespace AZ
const AZ::Data::AssetStreamInfo& streamInfo, bool isReload,
AssetHandler* handler, const AssetLoadParameters& loadParams, bool signalLoaded)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Set up the callback that will process the asset data once the raw file load is finished.
// The callback is declared as mutable so that we can clear weakAsset within the callback. The refcount in weakAsset
@@ -1613,7 +1613,7 @@ namespace AZ
if (loadingAsset)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "AZ::Data::LoadAssetStreamerCallback %s",
AZ_PROFILE_SCOPE(AzCore, "AZ::Data::LoadAssetStreamerCallback %s",
loadingAsset.GetHint().c_str());
{
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
@@ -1788,7 +1788,7 @@ namespace AZ
//=========================================================================
void AssetManager::RegisterAssetLoading(const Asset<AssetData>& asset)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AssetData* data = asset.Get();
if (data)
@@ -1803,7 +1803,7 @@ namespace AZ
//=========================================================================
void AssetManager::UnregisterAssetLoading([[maybe_unused]] const Asset<AssetData>& asset)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
}
//=========================================================================
@@ -2050,7 +2050,7 @@ namespace AZ
AZStd::shared_ptr<AssetDataStream> stream,
const AssetFilterCB& assetLoadFilterCB)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "AssetHandler::LoadAssetData - %s", asset.GetHint().c_str());
AZ_PROFILE_SCOPE(AzCore, "AssetHandler::LoadAssetData - %s", asset.GetHint().c_str());
#ifdef AZ_ENABLE_TRACING
auto start = AZStd::chrono::system_clock::now();
@@ -2119,7 +2119,7 @@ namespace AZ
void AssetManager::PostLoad(AZ::Data::Asset<AZ::Data::AssetData>& asset, bool loadSucceeded,
bool isReload, AZ::Data::AssetHandler* assetHandler)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!assetHandler)
{
assetHandler = GetHandler(asset.GetType());
@@ -19,7 +19,6 @@
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/Slice/SliceSystemComponent.h>
#include <AzCore/Slice/SliceMetadataInfoComponent.h>
#include <AzCore/Statistics/StatisticalProfilerProxySystemComponent.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/Time/TimeSystemComponent.h>
#include <AzCore/Console/LoggerSystemComponent.h>
@@ -45,9 +44,6 @@ namespace AZ
LoggerSystemComponent::CreateDescriptor(),
EventSchedulerSystemComponent::CreateDescriptor(),
#if !defined(_RELEASE)
Statistics::StatisticalProfilerProxySystemComponent::CreateDescriptor(),
#endif // #if !defined(_RELEASE)
#if !defined(AZCORE_EXCLUDE_LUA)
ScriptSystemComponent::CreateDescriptor(),
#endif // #if !defined(AZCORE_EXCLUDE_LUA)
@@ -61,10 +57,6 @@ namespace AZ
azrtti_typeid<TimeSystemComponent>(),
azrtti_typeid<LoggerSystemComponent>(),
azrtti_typeid<EventSchedulerSystemComponent>(),
#if !defined(_RELEASE)
azrtti_typeid<AZ::Statistics::StatisticalProfilerProxySystemComponent>(),
#endif // #if !defined(_RELEASE)
};
}
}
@@ -1394,8 +1394,7 @@ namespace AZ
void ComponentApplication::Tick(float deltaOverride /*= -1.f*/)
{
{
AZ_PROFILE_TIMER("System", "Component application simulation tick function");
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_SCOPE(System, "Component application simulation tick");
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
@@ -1408,12 +1407,12 @@ namespace AZ
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "ComponentApplication::Tick:ExecuteQueuedEvents");
AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:ExecuteQueuedEvents");
TickBus::ExecuteQueuedEvents();
}
m_currentTime = now;
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "ComponentApplication::Tick:OnTick");
AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
}
}
@@ -1428,8 +1427,7 @@ namespace AZ
//=========================================================================
void ComponentApplication::TickSystem()
{
AZ_PROFILE_TIMER("System", "Component application system tick function");
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_SCOPE(System, "Component application tick");
SystemTickBus::ExecuteQueuedEvents();
EBUS_EVENT(SystemTickBus, OnSystemTick);
@@ -11,7 +11,6 @@
#include <AzCore/Component/Component.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/Debug/ProfileModuleInit.h>
#include <AzCore/Memory/AllocationRecords.h>
#include <AzCore/Memory/OSAllocator.h>
#include <AzCore/Module/DynamicModuleHandle.h>
@@ -189,7 +189,7 @@ namespace AZ
void Entity::Activate()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(m_state == State::Init, "Entity should be in Init state to be Activated!");
@@ -226,7 +226,7 @@ namespace AZ
void Entity::Deactivate()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ::ComponentApplicationRequests* componentApplication = AZ::Interface<AZ::ComponentApplicationRequests>::Get();
if (componentApplication != nullptr)
@@ -1034,7 +1034,7 @@ namespace AZ
Entity::DependencySortOutcome Entity::DependencySort(ComponentArrayType& inOutComponents)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
using DependencySortInternal::ComponentInfo;
using DependencySortInternal::InvalidEntry;
@@ -40,7 +40,7 @@ namespace AZ
//=========================================================================
void EnumerateEntityIds(const void* classPtr, const Uuid& classUuid, const EntityIdVisitor& visitor, SerializeContext* context)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!context)
{
@@ -54,7 +54,7 @@ namespace AZ
template<class T>
unsigned int ReplaceEntityRefs(T* classPtr, const EntityIdMapper& mapper, SerializeContext* context = nullptr)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto idMapper = [&mapper](const EntityId& originalId, bool isEntityId, const IdUtils::Remapper<EntityId>::IdGenerator&) -> EntityId
{
return mapper(originalId, isEntityId);
@@ -83,7 +83,7 @@ namespace AZ
template<class T>
unsigned int ReplaceEntityIds(T* classPtr, const EntityIdMapper& mapper, SerializeContext* context = nullptr)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto idMapper = [&mapper](const EntityId& originalId, bool isEntityId, const IdUtils::Remapper<EntityId>::IdGenerator&) -> EntityId
{
return mapper(originalId, isEntityId);
@@ -97,7 +97,7 @@ namespace AZ
template<class T>
unsigned int ReplaceEntityIdsAndEntityRefs(T* classPtr, const EntityIdMapper& mapper, SerializeContext* context = nullptr)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto idMapper = [&mapper](const EntityId& originalId, bool isEntityId, const IdUtils::Remapper<EntityId>::IdGenerator&) -> EntityId
{
return mapper(originalId, isEntityId);
@@ -174,12 +174,28 @@ namespace AZ
}
}
bool Console::HasCommand(const char* command)
bool Console::ExecuteDeferredConsoleCommands()
{
auto DeferredCommandCallable = [this](const DeferredCommand& deferredCommand)
{
return this->DispatchCommand(deferredCommand.m_command, deferredCommand.m_arguments, deferredCommand.m_silentMode,
deferredCommand.m_invokedFrom, deferredCommand.m_requiredSet, deferredCommand.m_requiredClear);
};
// Attempt to invoke the deferred command and remove it from the queue if successful
return AZStd::erase_if(m_deferredCommands, DeferredCommandCallable) != 0;
}
void Console::ClearDeferredConsoleCommands()
{
m_deferredCommands = {};
}
bool Console::HasCommand(AZStd::string_view command)
{
return FindCommand(command) != nullptr;
}
ConsoleFunctorBase* Console::FindCommand(const char* command)
ConsoleFunctorBase* Console::FindCommand(AZStd::string_view command)
{
CVarFixedString lowerName(command);
AZStd::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), [](char value) { return std::tolower(value); });
@@ -200,11 +216,9 @@ namespace AZ
return nullptr;
}
AZStd::string Console::AutoCompleteCommand(const char* command, AZStd::vector<AZStd::string>* matches)
AZStd::string Console::AutoCompleteCommand(AZStd::string_view command, AZStd::vector<AZStd::string>* matches)
{
const size_t commandLength = strlen(command);
if (commandLength <= 0)
if (command.empty())
{
return command;
}
@@ -219,7 +233,7 @@ namespace AZ
continue;
}
if (StringFunc::Equal(curr->m_name, command, false, commandLength))
if (StringFunc::StartsWith(curr->m_name, command, false))
{
AZLOG_INFO("- %s : %s\n", curr->m_name, curr->m_desc);
commandSubset.push_back(curr->m_name);
@@ -498,7 +512,8 @@ namespace AZ
AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator };
AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator };
if (inputKey.IsRelativeTo(consoleRootCommandKey))
// The ConsoleRootComamndKey is not a command itself so strictly children keys are being examined
if (inputKey.IsRelativeTo(consoleRootCommandKey) && inputKey != consoleRootCommandKey)
{
FixedValueString command = inputKey.LexicallyRelative(consoleRootCommandKey).Native();
ConsoleCommandContainer commandArgs;
@@ -560,7 +575,24 @@ namespace AZ
commandTrace += commandArg;
}
m_console.PerformCommand(command, commandArgs, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null);
if (!m_console.PerformCommand(command, commandArgs, ConsoleSilentMode::NotSilent,
ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null))
{
// If the command could not be dispatched at this time add it to the
// deferred commands queue
using DeferredCommand = Console::DeferredCommand;
DeferredCommand deferredCommand
{
AZStd::string_view{command},
DeferredCommand::DeferredArguments{commandArgs.begin(), commandArgs.end()},
ConsoleSilentMode::NotSilent,
ConsoleInvokedFrom::AzConsole,
ConsoleFunctorFlags::Null,
ConsoleFunctorFlags::Null
};
m_console.m_deferredCommands.emplace_back(AZStd::move(deferredCommand));
}
}
}
+20 -3
View File
@@ -60,9 +60,13 @@ namespace AZ
) override;
void ExecuteConfigFile(AZStd::string_view configFileName) override;
void ExecuteCommandLine(const AZ::CommandLine& commandLine) override;
bool HasCommand(const char* command) override;
ConsoleFunctorBase* FindCommand(const char* command) override;
AZStd::string AutoCompleteCommand(const char* command, AZStd::vector<AZStd::string>* matches = nullptr) override;
bool ExecuteDeferredConsoleCommands() override;
void ClearDeferredConsoleCommands() override;
bool HasCommand(AZStd::string_view command) override;
ConsoleFunctorBase* FindCommand(AZStd::string_view command) override;
AZStd::string AutoCompleteCommand(AZStd::string_view command, AZStd::vector<AZStd::string>* matches = nullptr) override;
void VisitRegisteredFunctors(const FunctorVisitor& visitor) override;
void RegisterFunctor(ConsoleFunctorBase* functor) override;
void UnregisterFunctor(ConsoleFunctorBase* functor) override;
@@ -98,7 +102,20 @@ namespace AZ
using CommandMap = AZStd::unordered_map<CVarFixedString, AZStd::vector<ConsoleFunctorBase*>>;
CommandMap m_commands;
AZ::SettingsRegistryInterface::NotifyEventHandler m_consoleCommandKeyHandler;
struct DeferredCommand
{
using DeferredArguments = AZStd::vector<AZStd::string>;
AZStd::string m_command;
DeferredArguments m_arguments;
ConsoleSilentMode m_silentMode;
ConsoleInvokedFrom m_invokedFrom;
ConsoleFunctorFlags m_requiredSet;
ConsoleFunctorFlags m_requiredClear;
};
using DeferredCommandQueue = AZStd::deque<DeferredCommand>;
DeferredCommandQueue m_deferredCommands;
friend struct ConsoleCommandKeyNotificationHandler;
friend class ConsoleFunctorBase;
};
}
@@ -94,22 +94,30 @@ namespace AZ
//! @param commandLine the concatenated command-line string to execute
virtual void ExecuteCommandLine(const AZ::CommandLine& commandLine) = 0;
//! Attempts to invoke a "deferred console command", which is a console command
//! that has failed to execute previously due to the command not being registered yet.
//! @return boolean true if any deferred console commands have executed, false otherwise
virtual bool ExecuteDeferredConsoleCommands() = 0;
//! Clear out any deferred console commands queue
virtual void ClearDeferredConsoleCommands() = 0;
//! HasCommand is used to determine if the console knows about a command.
//! @param command the command we are checking for
//! @return boolean true on if the command is registered, false otherwise
virtual bool HasCommand(const char* command) = 0;
virtual bool HasCommand(AZStd::string_view command) = 0;
//! FindCommand finds the console command with the specified console string.
//! @param command the command that is being searched for
//! @return non-null pointer to the console command if found
virtual ConsoleFunctorBase* FindCommand(const char* command) = 0;
virtual ConsoleFunctorBase* FindCommand(AZStd::string_view command) = 0;
//! Finds all commands where the input command is a prefix and returns
//! the longest matching substring prefix the results have in common.
//! @param command The prefix string to find all matching commands for.
//! @param matches The list of all commands that match the input prefix.
//! @return The longest matching substring prefix the results have in common.
virtual AZStd::string AutoCompleteCommand(const char* command,
virtual AZStd::string AutoCompleteCommand(AZStd::string_view command,
AZStd::vector<AZStd::string>* matches = nullptr) = 0;
//! Retrieves the value of the requested cvar.
@@ -117,7 +125,7 @@ namespace AZ
//! @param outValue reference to the instance to write the current cvar value to
//! @return GetValueResult::Success if the operation succeeded, or an error result if the operation failed
template<typename RETURN_TYPE>
GetValueResult GetCvarValue(const char* command, RETURN_TYPE& outValue);
GetValueResult GetCvarValue(AZStd::string_view command, RETURN_TYPE& outValue);
//! Visits all registered console functors.
//! @param visitor the instance to visit all functors with
@@ -176,7 +184,7 @@ namespace AZ
}
template<typename RETURN_TYPE>
inline GetValueResult IConsole::GetCvarValue(const char* command, RETURN_TYPE& outValue)
inline GetValueResult IConsole::GetCvarValue(AZStd::string_view command, RETURN_TYPE& outValue)
{
ConsoleFunctorBase* cvarFunctor = FindCommand(command);
if (cvarFunctor == nullptr)
@@ -38,17 +38,6 @@ namespace AZ
}
}
#ifdef AZ_PROFILE_TELEMETRY
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category) AZ::Debug::EventTrace::ScopedSlice AZ_JOIN(ScopedSlice__, __LINE__)(name, category);
# define AZ_TRACE_METHOD_NAME(name) \
AZ_TRACE_METHOD_NAME_CATEGORY(name, "") \
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzTrace, name)
# define AZ_TRACE_METHOD() \
AZ_TRACE_METHOD_NAME_CATEGORY(AZ_FUNCTION_SIGNATURE, "") \
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzTrace)
#else
# define AZ_TRACE_METHOD_NAME_CATEGORY(name, category)
# define AZ_TRACE_METHOD_NAME(name) AZ_TRACE_METHOD_NAME_CATEGORY(name, "")
# define AZ_TRACE_METHOD() AZ_TRACE_METHOD_NAME(AZ_FUNCTION_SIGNATURE)
#endif
#define AZ_TRACE_METHOD_NAME_CATEGORY(name, category)
#define AZ_TRACE_METHOD_NAME(name) AZ_TRACE_METHOD_NAME_CATEGORY(name, "")
#define AZ_TRACE_METHOD() AZ_TRACE_METHOD_NAME(AZ_FUNCTION_SIGNATURE)
@@ -0,0 +1,16 @@
/*
* 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
#ifndef AZ_PROFILE_MEMORY_ALLOC
// No other profiler has defined the performance markers AZ_PROFILE_MEMORY_ALLOC (and friends), fall back to a Driller implementation (currently empty)
# define AZ_PROFILE_MEMORY_ALLOC(category, address, size, context)
# define AZ_PROFILE_MEMORY_ALLOC_EX(category, filename, lineNumber, address, size, context)
# define AZ_PROFILE_MEMORY_FREE(category, address)
# define AZ_PROFILE_MEMORY_FREE_EX(category, filename, lineNumber, address)
#endif
@@ -1,53 +0,0 @@
/*
* 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/Debug/ProfileModuleInit.h>
#ifdef AZ_PROFILE_TELEMETRY
# include <RADTelemetry/ProfileTelemetryBus.h>
// Define the per-module RAD Telemetry instance pointer
struct tm_api;
tm_api* g_radTmApi;
#endif
namespace AZ
{
namespace Debug
{
void ProfileModuleInit()
{
#if defined(AZ_PROFILE_TELEMETRY)
{
if (!g_radTmApi)
{
using namespace RADTelemetry;
ProfileTelemetryRequestBus::BroadcastResult(g_radTmApi, &ProfileTelemetryRequests::GetApiInstance);
}
}
#endif
// Add additional per-DLL required profiler initialization here
}
ProfileModuleInitializer::ProfileModuleInitializer()
{
ProfilerNotificationBus::Handler::BusConnect();
}
ProfileModuleInitializer::~ProfileModuleInitializer()
{
ProfilerNotificationBus::Handler::BusDisconnect();
}
void ProfileModuleInitializer::OnProfileSystemInitialized()
{
ProfileModuleInit();
}
}
}
@@ -1,36 +0,0 @@
/*
* 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/Debug/ProfilerBus.h>
namespace AZ
{
namespace Debug
{
//! Perform any required per-module initialization of the current profiler
void ProfileModuleInit();
/*!
* ProfileModuleInitializer
* Helper class that calls ProfileModuleInit when OnProfileSystemInitialized is fired.
*/
class ProfileModuleInitializer
: private AZ::Debug::ProfilerNotificationBus::Handler
{
public:
ProfileModuleInitializer();
~ProfileModuleInitializer() override;
private:
void OnProfileSystemInitialized() override;
};
}
}
@@ -20,6 +20,12 @@
namespace AZ
{
uint32_t ProfileScope::GetSystemID(const char* system)
{
// TODO: stable ids for registered budgets
return AZ::Crc32(system);
}
namespace Debug
{
//////////////////////////////////////////////////////////////////////////
@@ -537,6 +543,7 @@ namespace AZ
void ProfilerRegister::TimerStart(ProfilerSection* section)
{
ProfilerRegister* reg = this;
if (reg->m_isActive)
{
section->m_register = reg;
+62 -288
View File
@@ -5,310 +5,44 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef AZCORE_PROFILER_H
#define AZCORE_PROFILER_H 1
#pragma once
#include <AzCore/std/chrono/chrono.h>
#include <AzCore/std/function/function_fwd.h>
namespace AZ
{
namespace Debug
{
using ProfileCategoryPrimitiveType = AZ::u64;
/**
* Profiling categories consumed by AZ_PROFILE_FUNCTION and AZ_PROFILE_SCOPE variants for profile filtering
*/
enum class ProfileCategory : ProfileCategoryPrimitiveType
{
// These initial categories match up with the legacy EProfiledSubsystem categories
Any = 0,
Renderer,
ThreeDEngine,
Particle,
AI,
Animation,
Movie,
Entity,
Font,
Network,
Physics,
Script,
ScriptCFunc,
Audio,
Editor,
System,
Action,
Game,
Input,
Sync,
// Legacy network traffic categories
LegacyNetworkTrafficReserved,
LegacyDeviceReserved,
// must match EProfiledSubsystem::PROFILE_LAST_SUBSYSTEM
LegacyLast,
// Bulk category via AZ_TRACE_METHOD
AzTrace,
AzCore,
AzRender,
AzFramework,
AzToolsFramework,
ScriptCanvas,
LegacyTerrain,
Terrain,
Cloth,
// Add new major categories here (and add names to the parallel position in ProfileCategoryNames) - these categories are enabled by default
FirstDetailedCategory,
RendererDetailed = FirstDetailedCategory,
ThreeDEngineDetailed,
JobManagerDetailed,
AzRenderDetailed,
ClothDetailed,
// Add new detailed categories here (and add names to the parallel position in ProfileCategoryNames) -- these categories are disabled by default
// Internal reserved categories, not for use with performance events
FirstReservedCategory,
MemoryReserved = FirstReservedCategory,
Global,
// Must be last
Count
};
static_assert(static_cast<size_t>(ProfileCategory::Count) < (sizeof(ProfileCategoryPrimitiveType) * 8), "The number of profile categories must not exceed the number of bits in ProfileCategoryPrimitiveType");
/**
* Parallel array to ProfileCategory as string category names to be used as Driller category names or for debug purposes
*/
static const char * ProfileCategoryNames[] =
{
"Any",
"Renderer",
"3DEngine",
"Particle",
"AI",
"Animation",
"Movie",
"Entity",
"Font",
"Network",
"Physics",
"Script",
"ScriptCFunc",
"Audio",
"Editor",
"System",
"Action",
"Game",
"Input",
"Sync",
"LegacyNetworkTrafficReserved",
"LegacyDeviceReserved",
"LegacyLast",
"AzTrace",
"AzCore",
"AzRender",
"AzFramework",
"AzToolsFramework",
"ScriptCanvas",
"LegacyTerrain",
"Terrain",
"Cloth",
"RendererDetailed",
"3DEngineDetailed",
"JobManagerDetailed",
"AzRenderDetailed",
"ClothDetailed",
"MemoryReserved",
"Global"
};
static_assert(AZ_ARRAY_SIZE(ProfileCategoryNames) == static_cast<size_t>(ProfileCategory::Count), "ProfileCategory and ProfileCategoryNames size mismatch");
}
}
// Must be included below ProfileCategory
#ifdef AZ_PROFILE_TELEMETRY
# include <RADTelemetry/ProfileTelemetry.h>
#ifdef USE_PIX
#include <AzCore/PlatformIncl.h>
#include <WinPixEventRuntime/pix3.h>
#endif
#if defined(AZ_PROFILER_MACRO_DISABLE) // by default we never disable the profiler registers as their overhead should be minimal, you can still do that for your code though.
# define AZ_PROFILE_TIMER(...)
# define AZ_PROFILE_TIMER_END(_SectionVariableName)
# define AZ_PROFILE_VALUE_SET(...)
# define AZ_PROFILE_VALUE_ADD(...)
# define AZ_PROFILE_VALUE_SET_NAMED(...)
# define AZ_PROFILE_VALUE_ADD_NAMED(...)
# define AZ_PROFILE_SCOPE(...)
# define AZ_PROFILE_FUNCTION(...)
# define AZ_PROFILE_BEGIN(...)
# define AZ_PROFILE_END(...)
#else
/// Implementation when we have only 1 param system name
# define AZ_PROFILE_TIMER_1(_1) AZ_PROFILE_TIMER_2(_1, nullptr)
/// Implementation when we have 2 params (_1 system name and _2 is name of the "section"/register/profiled section - used for debug)
# define AZ_PROFILE_TIMER_2(_1, _2) AZ_PROFILE_TIMER_3(_1, _2, AZ_JOIN(azProfileSection, __LINE__))
/// Implementation when we have all 3 params (system name, section/register name, section variable name)
# define AZ_PROFILE_TIMER_3(_1, _2, _3) \
AZ::Debug::ProfilerSection _3; \
if (AZ::u64 profilerId = AZ::Debug::Profiler::GetId()) { \
static AZ_THREAD_LOCAL AZ::Internal::RegisterData AZ_JOIN(azProfileRegister, __LINE__) = {0, 0}; \
if (AZ_JOIN(azProfileRegister, __LINE__).m_profilerId != profilerId) { \
AZ_JOIN(azProfileRegister, __LINE__).m_register = AZ::Debug::ProfilerRegister::TimerCreateAndStart(_1, _2, &_3, AZ_FUNCTION_SIGNATURE, __LINE__); \
AZ_JOIN(azProfileRegister, __LINE__).m_profilerId = profilerId; \
} else { \
AZ_JOIN(azProfileRegister, __LINE__).m_register->TimerStart(&_3); \
} \
}
/**
* Macro to declare a profile section for the current scope { }.
* format is: AZ_PROFILE_TIMER(const char* systemName, const char* sectionDescription = nullptr , optional sectionName )
* \param _1 is required and it's 'const char*' of the system name of which system this scope/register belongs to.
* \param _2 is optional and it's 'const char*' with a name for the "section"/register/profiled section - used as description. If not provided a "Anonymous" will be set.
* \param _3 is optional unique name for a section C++ variable (so you can stop the SCOPE as you wish). If not provided a default unique name is created.
* format is: AZ_PROFILE_SCOPE(categoryName, const char* formatStr, ...)
*/
# define AZ_PROFILE_TIMER(...) AZ_MACRO_SPECIALIZE(AZ_PROFILE_TIMER_, AZ_VA_NUM_ARGS(__VA_ARGS__), (__VA_ARGS__))
// Optional (USE ONLY IN EXTREME CASES!!!) scope end command for named sections, so you stop the profiler register timing before it goes out of scope.
# define AZ_PROFILE_TIMER_END(_SectionVariableName) { _SectionVariableName.Stop(); }
/**
* Macro to operate on custom values. All values are AZ::s64. You can provide up to 5 values.
* format is AZ_PROFILE_VALUE_SET/ADD(const char* systemName, const char* valueName,
* value1, optional value2, optional value3, optional value 4, optional value5, optional registerName (for direct register manipulation for EXPERTS ONLY)).
* \param _SystemName is required and it's 'const char*' of the system name of which system this scope/register belongs to.
* \param _RegisterName is required and it's 'const char*' with a name for the register - used as description.
* \param 3 is required and it's AZ::s64, operates on m_value1.
* \param 4 is optional and it's AZ::s64, operates on m_value2.
* \param 5 is optional and it's AZ::s64, operates on m_value3.
* \param 6 is optional and it's AZ::s64, operates on m_value4.
* \param 7 is optional and it's AZ::s64, operates on m_value5.
*/
# define AZ_PROFILE_VALUE_SET(_SystemName, _RegisterName, ...) \
if (AZ::u64 profilerId = AZ::Debug::Profiler::GetId()) { \
static AZ_THREAD_LOCAL AZ::Internal::RegisterData AZ_JOIN(azProfileRegister, __LINE__) = {0, 0}; \
if (AZ_JOIN(azProfileRegister, __LINE__).m_profilerId != profilerId) { \
AZ_JOIN(azProfileRegister, __LINE__).m_register = AZ::Debug::ProfilerRegister::ValueCreate(_SystemName, _RegisterName, AZ_FUNCTION_SIGNATURE, __LINE__); \
AZ_JOIN(azProfileRegister, __LINE__).m_profilerId = profilerId; \
} \
AZ_JOIN(azProfileRegister, __LINE__).m_register->ValueSet(__VA_ARGS__); \
}
/// Same as AZ_PROFILE_VALUE_SET except is add the values passed in the macro (you can use -(value), to subtract values)
# define AZ_PROFILE_VALUE_ADD(_SystemName, _RegisterName, ...) \
if (AZ::u64 profilerId = AZ::Debug::Profiler::GetId()) { \
static AZ_THREAD_LOCAL AZ::Internal::RegisterData AZ_JOIN(azProfileRegister, __LINE__) = {0, 0}; \
if (AZ_JOIN(azProfileRegister, __LINE__).m_profilerId != profilerId) { \
AZ_JOIN(azProfileRegister, __LINE__).m_register = AZ::Debug::ProfilerRegister::ValueCreate(_SystemName, _RegisterName, AZ_FUNCTION_SIGNATURE, __LINE__); \
AZ_JOIN(azProfileRegister, __LINE__).m_profilerId = profilerId; \
} \
AZ_JOIN(azProfileRegister, __LINE__).m_register->ValueAdd(__VA_ARGS__); \
}
/**
* Same as AZ_PROFILER_VALUE_SET but with option to access the register by name. (USE ONLY IN EXTREME CASES!!!)
* \param _RegisterVaribaleName is optional unique name for a register C++ variable so you can manipulate the register.
*/
# define AZ_PROFILE_VALUE_SET_NAMED(_SystemName, _RegisterName, _RegisterVaribaleName, ...) \
AZ::Debug::ProfilerRegister * _RegisterVaribaleName = nullptr; \
if (AZ::u64 profilerId = AZ::Debug::Profiler::GetId()) { \
static AZ_THREAD_LOCAL AZ::Internal::RegisterData AZ_JOIN(azProfileRegister, __LINE__) = {0, 0}; \
if (AZ_JOIN(azProfileRegister, __LINE__).m_profilerId != profilerId) { \
AZ_JOIN(azProfileRegister, __LINE__).m_register = AZ::Debug::ProfilerRegister::ValueCreate(_SystemName, _RegisterName, AZ_FUNCTION_SIGNATURE, __LINE__); \
AZ_JOIN(azProfileRegister, __LINE__).m_profilerId = profilerId; \
} \
AZ_JOIN(azProfileRegister, __LINE__).m_register->ValueSet(__VA_ARGS__); \
_RegisterVaribaleName = AZ_JOIN(azProfileRegister, __LINE__).m_register; \
}
/// Same as AZ_PROFILE_VALUE_SET_NAMED but add the values to the current. (USE ONLY IN EXTREME CASES!!!)
# define AZ_PROFILE_VALUE_ADD_NAMED(_SystemName, _RegisterName, _RegisterVaribaleName, ...) \
AZ::Debug::ProfilerRegister * _RegisterVaribaleName = nullptr; \
if (AZ::u64 profilerId = AZ::Debug::Profiler::GetId()) { \
static AZ_THREAD_LOCAL AZ::Internal::RegisterData AZ_JOIN(azProfileRegister, __LINE__) = {0, 0}; \
if (AZ_JOIN(azProfileRegister, __LINE__).m_profilerId != profilerId) { \
AZ_JOIN(azProfileRegister, __LINE__).m_register = AZ::Debug::ProfilerRegister::ValueCreate(_SystemName, _RegisterName, AZ_FUNCTION_SIGNATURE, __LINE__); \
AZ_JOIN(azProfileRegister, __LINE__).m_profilerId = profilerId; \
} \
AZ_JOIN(azProfileRegister, __LINE__).m_register->ValueAdd(__VA_ARGS__); \
_RegisterVaribaleName = AZ_JOIN(azProfileRegister, __LINE__).m_register; \
}
# define AZ_PROFILE_SCOPE(category, ...) ::AZ::ProfileScope AZ_JOIN(azProfileScope, __LINE__){ #category, __VA_ARGS__ }
# define AZ_PROFILE_FUNCTION(category) AZ_PROFILE_SCOPE(category, AZ_FUNCTION_SIGNATURE)
// Prefer using the scoped macros which automatically end the event (AZ_PROFILE_SCOPE/AZ_PROFILE_FUNCTION)
# define AZ_PROFILE_BEGIN(category, ...) ::AZ::ProfileScope::BeginRegion(#category, __VA_ARGS__)
# define AZ_PROFILE_END() ::AZ::ProfileScope::EndRegion()
#endif // AZ_PROFILER_MACRO_DISABLE
#ifndef AZ_PROFILE_FUNCTION
// No other profiler has defined the performance markers AZ_PROFILE_SCOPE (and friends), fallback to a Driller implementation
# define AZ_INTERNAL_PROF_VERIFY_CAT(category) static_assert(category < AZ::Debug::ProfileCategory::Count, "Invalid profile category")
# define AZ_INTERNAL_PROF_CAT_NAME(category) AZ::Debug::ProfileCategoryNames[static_cast<AZ::u32>(category)]
# define AZ_PROFILE_FUNCTION(category) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
# define AZ_PROFILE_FUNCTION_STALL(category) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
# define AZ_PROFILE_FUNCTION_IDLE(category) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
# define AZ_PROFILE_SCOPE(category, name) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category)); (void)(name)
# define AZ_PROFILE_SCOPE_STALL(category, name) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category)); (void)(name)
# define AZ_PROFILE_SCOPE_IDLE(category, name) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category)); (void)(name)
# define AZ_PROFILE_SCOPE_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
# define AZ_PROFILE_SCOPE_STALL_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
# define AZ_PROFILE_SCOPE_IDLE_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_PROFILE_TIMER(AZ_INTERNAL_PROF_CAT_NAME(category))
#endif
#ifndef AZ_PROFILE_EVENT_BEGIN
// No other profiler has defined the performance markers AZ_PROFILE_EVENT_START/END, fallback to a Driller implementation (currently empty)
# define AZ_PROFILE_EVENT_BEGIN(category, name) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); (void)(name)
# define AZ_PROFILE_EVENT_END(category) \
AZ_INTERNAL_PROF_VERIFY_CAT(category)
#endif
#ifndef AZ_PROFILE_INTERVAL_START
// No other profiler has defined the performance markers AZ_PROFILE_INTERVAL_START/END, fallback to a Driller implementation (currently empty)
# define AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id) static_assert(sizeof(id) <= sizeof(AZ::u64), "Interval id must be a unique value no larger than 64-bits")
# define AZ_PROFILE_INTERVAL_START(category, id, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id)
# define AZ_PROFILE_INTERVAL_START_COLORED(category, id, color, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); (void)(color); AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id)
# define AZ_PROFILE_INTERVAL_END(category, id) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id)
# define AZ_PROFILE_INTERVAL_SCOPED(category, id, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id)
# define AZ_PROFILE_INTERVAL_START(...)
# define AZ_PROFILE_INTERVAL_START_COLORED(...)
# define AZ_PROFILE_INTERVAL_END(...)
# define AZ_PROFILE_INTERVAL_SCOPED(...)
#endif
#ifndef AZ_PROFILE_DATAPOINT
// No other profiler has defined the performance markers AZ_PROFILE_DATAPOINT, fallback to a Driller implementation (currently empty)
#define AZ_PROFILE_DATAPOINT(category, value, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); static_cast<double>(value)
#define AZ_PROFILE_DATAPOINT_PERCENT(category, value, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); static_cast<double>(value)
#endif
#ifndef AZ_PROFILE_MEMORY_ALLOC
// No other profiler has defined the performance markers AZ_PROFILE_MEMORY_ALLOC (and friends), fall back to a Driller implementation (currently empty)
# define AZ_PROFILE_MEMORY_ALLOC(category, address, size, context) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); (void)(context)
# define AZ_PROFILE_MEMORY_ALLOC_EX(category, filename, lineNumber, address, size, context) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); (void)(context)
# define AZ_PROFILE_MEMORY_FREE(category, address) \
AZ_INTERNAL_PROF_VERIFY_CAT(category)
# define AZ_PROFILE_MEMORY_FREE_EX(category, filename, lineNumber, address) \
AZ_INTERNAL_PROF_VERIFY_CAT(category)
# define AZ_PROFILE_DATAPOINT(...)
# define AZ_PROFILE_DATAPOINT_PERCENT(...)
#endif
namespace AZStd
@@ -318,6 +52,42 @@ namespace AZStd
namespace AZ
{
class ProfileScope
{
public:
static uint32_t GetSystemID(const char* system);
template<typename... T>
static void BeginRegion([[maybe_unused]] const char* system, [[maybe_unused]] const char* eventName, [[maybe_unused]] T const&... args)
{
// TODO: Verification that the supplied system name corresponds to a known budget
#if defined(USE_PIX)
PIXBeginEvent(PIX_COLOR_INDEX(GetSystemID(system) & 0xff), eventName, args...);
#endif
// TODO: injecting instrumentation for other profilers
// NOTE: external profiler registration won't occur inline in a header necessarily in this manner, but the exact mechanism
// will be introduced in a future PR
}
static void EndRegion()
{
#if defined(USE_PIX)
PIXEndEvent();
#endif
}
template<typename... T>
ProfileScope(const char* system, char const* eventName, T const&... args)
{
BeginRegion(system, eventName, args...);
}
~ProfileScope()
{
EndRegion();
}
};
namespace Debug
{
class ProfilerSection;
@@ -615,5 +385,9 @@ namespace AZ
}
} // namespace AZ
#endif // AZCORE_PROFILER_H
#pragma once
#ifdef USE_PIX
// The pix3 header unfortunately brings in other Windows macros we need to undef
#undef DeleteFile
#undef LoadImage
#undef GetCurrentTime
#endif
+5 -4
View File
@@ -13,6 +13,7 @@
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/PlatformIncl.h>
#include <AzCore/Debug/Profiler.h>
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
@@ -353,7 +354,7 @@ namespace AZ
m_filename = path;
}
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, &m_filename, 0xff0000ff, "FileIO: %s", m_filename.c_str());
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, &m_filename, 0xff0000ff, "FileIO: %s", m_filename.c_str());
return result;
}
@@ -372,7 +373,7 @@ namespace AZ
FileIOBase::GetInstance()->Close(m_handle);
m_handle = InvalidHandle;
m_ownsHandle = false;
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::AzCore, &m_filename);
AZ_PROFILE_INTERVAL_END(AzCore, &m_filename);
}
}
@@ -425,7 +426,7 @@ namespace AZ
void FileIOStream::Seek(OffsetType bytes, SeekMode mode)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "FileIO Seek: %s", m_filename.c_str());
AZ_PROFILE_SCOPE(AzCore, "FileIO Seek: %s", m_filename.c_str());
AZ_Assert(FileIOBase::GetInstance(), "FileIO is not initialized.");
AZ_Assert(IsOpen(), "Cannot seek on a FileIOStream that is not open.");
@@ -453,7 +454,7 @@ namespace AZ
SizeType FileIOStream::Read(SizeType bytes, void* oBuffer)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "FileIO Read: %s", m_filename.c_str());
AZ_PROFILE_SCOPE(AzCore, "FileIO Read: %s", m_filename.c_str());
AZ_Assert(FileIOBase::GetInstance(), "FileIO is not initialized.");
AZ_Assert(IsOpen(), "Cannot read from a FileIOStream that is not open.");
@@ -7,6 +7,7 @@
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/Streamer/BlockCache.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/Streamer/StreamerContext.h>
@@ -245,7 +246,7 @@ namespace AZ
auto continueReadFile = [this, request](FileRequest& fileSizeRequest)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(m_numMetaDataRetrievalInProgress > 0,
"More requests have completed meta data retrieval in the Block Cache than were requested.");
m_numMetaDataRetrievalInProgress--;
@@ -454,7 +455,7 @@ namespace AZ
section.m_readSize, sharedRead);
readRequest->SetCompletionCallback([this](FileRequest& request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
CompleteRead(request);
});
section.m_cacheBlockIndex = cacheLocation;
@@ -7,6 +7,7 @@
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/CompressionBus.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/Streamer/FullFileDecompressor.h>
@@ -367,7 +368,7 @@ namespace AZ
{
auto callback = [this, nextRequest](const FileRequest& checkRequest)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto check = AZStd::get_if<FileRequest::FileExistsCheckData>(&checkRequest.GetCommand());
AZ_Assert(check,
"Callback in FullFileDecompressor::PrepareReadRequest expected FileExistsCheck but got another command.");
@@ -426,7 +427,7 @@ namespace AZ
{
auto callback = [this, nextRequest](const FileRequest& checkRequest)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto check = AZStd::get_if<FileRequest::FileExistsCheckData>(&checkRequest.GetCommand());
AZ_Assert(check,
"Callback in FullFileDecompressor::PrepareDedicatedCache expected FileExistsCheck but got another command.");
@@ -508,7 +509,7 @@ namespace AZ
archiveReadRequest->SetCompletionCallback(
[this, readSlot = i](FileRequest& request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
FinishArchiveRead(&request, readSlot);
});
m_next->QueueRequest(archiveReadRequest);
@@ -596,7 +597,7 @@ namespace AZ
waitRequest->SetCompletionCallback([this, jobSlot](FileRequest& request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
FinishDecompression(&request, jobSlot);
});
@@ -7,6 +7,7 @@
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/IO/Streamer/ReadSplitter.h>
#include <AzCore/IO/Streamer/StreamerContext.h>
@@ -218,7 +219,7 @@ namespace AZ
subRequest->CreateRead(pending.m_request, pending.m_output, bufferSize, data->m_path, pending.m_offset, readSize, data->m_sharedRead);
subRequest->SetCompletionCallback([this](FileRequest&)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
QueuePendingRequest();
});
m_next->QueueRequest(subRequest);
@@ -302,7 +303,7 @@ namespace AZ
offset, readSize, data->m_sharedRead);
subRequest->SetCompletionCallback([this, bufferSlot]([[maybe_unused]] FileRequest& request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
BufferCopyInformation& copyInfo = m_bufferCopyInformation[bufferSlot];
memcpy(copyInfo.m_target, GetBufferSlot(bufferSlot) + copyInfo.m_bufferOffset, copyInfo.m_size);
@@ -7,6 +7,7 @@
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/Streamer/Scheduler.h>
#include <AzCore/std/containers/deque.h>
#include <AzCore/std/sort.h>
@@ -138,14 +139,14 @@ namespace AZ::IO
while (m_isRunning)
{
{
AZ_PROFILE_SCOPE_IDLE(AZ::Debug::ProfileCategory::AzCore, "Scheduler suspended.");
AZ_PROFILE_SCOPE(AzCore, "Scheduler suspended.");
m_context.SuspendSchedulingThread();
}
// Only do processing if the thread hasn't been suspended.
while (!m_isSuspended)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "Scheduler main loop.");
AZ_PROFILE_SCOPE(AzCore, "Scheduler main loop.");
// Always schedule requests first as the main Streamer thread could have been asleep for a long time due to slow reading
// but also don't schedule after every change in the queue as scheduling is not cheap.
@@ -154,7 +155,7 @@ namespace AZ::IO
{
do
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "Scheduler queue requests.");
AZ_PROFILE_SCOPE(AzCore, "Scheduler queue requests.");
// If there are pending requests and available slots, queue the next requests.
while(m_context.GetNumPreparedRequests() > 0)
{
@@ -208,7 +209,7 @@ namespace AZ::IO
void Scheduler::Thread_QueueNextRequest()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
FileRequest* next = m_context.PopPreparedRequest();
next->SetStatus(IStreamerTypes::RequestStatus::Processing);
@@ -279,7 +280,7 @@ namespace AZ::IO
m_processingSize += info.m_uncompressedSize;
#endif
}
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, next, ProfilerColor,
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, next, ProfilerColor,
"Streamer queued %zu: %s", next->GetCommand().index(), parentReadRequest->m_path.GetRelativePath());
m_threadData.m_streamStack->QueueRequest(next);
}
@@ -293,7 +294,7 @@ namespace AZ::IO
}
else if constexpr (AZStd::is_same_v<Command, FileRequest::FlushData> || AZStd::is_same_v<Command, FileRequest::FlushAllData>)
{
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, next, ProfilerColor,
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, next, ProfilerColor,
"Streamer queued %zu", next->GetCommand().index());
// Flushing becomes a lot less complicated if there are no jobs and/or asynchronous I/O running. This does mean overall
// longer processing time as bubbles are introduced into the pipeline, but flushing is an infrequent event that only
@@ -303,7 +304,7 @@ namespace AZ::IO
}
else
{
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, next, ProfilerColor,
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, next, ProfilerColor,
"Streamer queued %zu", next->GetCommand().index());
m_threadData.m_streamStack->QueueRequest(next);
}
@@ -312,13 +313,13 @@ namespace AZ::IO
bool Scheduler::Thread_ExecuteRequests()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
return m_threadData.m_streamStack->ExecuteRequests();
}
bool Scheduler::Thread_PrepareRequests(AZStd::vector<FileRequestPtr>& outstandingRequests)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
{
AZStd::scoped_lock lock(m_pendingRequestsLock);
@@ -372,7 +373,7 @@ namespace AZ::IO
void Scheduler::Thread_ProcessTillIdle()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
while (true)
{
@@ -390,7 +391,7 @@ namespace AZ::IO
void Scheduler::Thread_ProcessCancelRequest(FileRequest* request, FileRequest::CancelData& data)
{
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, request, ProfilerColor, "Streamer queued cancel");
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued cancel");
auto& pending = m_context.GetPreparedRequests();
auto pendingIt = pending.begin();
while (pendingIt != pending.end())
@@ -412,7 +413,7 @@ namespace AZ::IO
void Scheduler::Thread_ProcessRescheduleRequest(FileRequest* request, FileRequest::RescheduleData& data)
{
AZ_PROFILE_INTERVAL_START_COLORED(AZ::Debug::ProfileCategory::AzCore, request, ProfilerColor, "Streamer queued reschedule");
AZ_PROFILE_INTERVAL_START_COLORED(AzCore, request, ProfilerColor, "Streamer queued reschedule");
auto& pendingRequests = m_context.GetPreparedRequests();
for (FileRequest* pending : pendingRequests)
{
@@ -543,7 +544,7 @@ namespace AZ::IO
void Scheduler::Thread_ScheduleRequests()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
auto& pendingQueue = m_context.GetPreparedRequests();
@@ -554,7 +555,7 @@ namespace AZ::IO
if (m_context.GetNumPreparedRequests() > 1)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore,
AZ_PROFILE_SCOPE(AzCore,
"Scheduler::Thread_ScheduleRequests - Sorting %i requests", m_context.GetNumPreparedRequests());
auto sorter = [this](const FileRequest* lhs, const FileRequest* rhs) -> bool
{
@@ -48,7 +48,7 @@ namespace AZ
[[maybe_unused]] AZStd::string_view name,
[[maybe_unused]] double value)
{
AZ_PROFILE_DATAPOINT(AZ::Debug::ProfileCategory::AzCore, value,
AZ_PROFILE_DATAPOINT(AzCore, value,
"Streamer/%.*s/%.*s (Raw)",
aznumeric_cast<int>(owner.size()), owner.data(),
aznumeric_cast<int>(name.size()), name.data());
@@ -59,7 +59,7 @@ namespace AZ
void StorageDrive::PrepareRequest(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(request, "PrepareRequest was provided a null request.");
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
@@ -254,7 +254,7 @@ namespace AZ
void StorageDrive::ReadFile(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
AZ_Assert(data, "FileRequest queued on StorageDrive to be read didn't contain read data.");
@@ -341,7 +341,7 @@ namespace AZ
void StorageDrive::FileExistsRequest(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileExistsTimeAverage);
auto& fileExists = AZStd::get<FileRequest::FileExistsCheckData>(request->GetCommand());
@@ -359,7 +359,7 @@ namespace AZ
void StorageDrive::FileMetaDataRetrievalRequest(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileMetaDataTimeAverage);
auto& command = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
@@ -7,6 +7,7 @@
*/
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/CompressionBus.h>
#include <AzCore/IO/Streamer/Streamer.h>
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
@@ -262,15 +263,15 @@ namespace AZ::IO
switch (stat.GetType())
{
case Statistic::Type::FloatingPoint:
AZ_PROFILE_DATAPOINT(AZ::Debug::ProfileCategory::AzCore, stat.GetFloatValue(), "Streamer/%.*s/%.*s",
AZ_PROFILE_DATAPOINT(AzCore, stat.GetFloatValue(), "Streamer/%.*s/%.*s",
aznumeric_cast<int>(stat.GetOwner().length()), stat.GetOwner().data(), aznumeric_cast<int>(stat.GetName().length()), stat.GetName().data());
break;
case Statistic::Type::Integer:
AZ_PROFILE_DATAPOINT(AZ::Debug::ProfileCategory::AzCore, stat.GetIntegerValue(), "Streamer/%.*s/%.*s",
AZ_PROFILE_DATAPOINT(AzCore, stat.GetIntegerValue(), "Streamer/%.*s/%.*s",
aznumeric_cast<int>(stat.GetOwner().length()), stat.GetOwner().data(), aznumeric_cast<int>(stat.GetName().length()), stat.GetName().data());
break;
case Statistic::Type::Percentage:
AZ_PROFILE_DATAPOINT_PERCENT(AZ::Debug::ProfileCategory::AzCore, stat.GetPercentage(), "Streamer/%.*s/%.*s (percent)",
AZ_PROFILE_DATAPOINT_PERCENT(AzCore, stat.GetPercentage(), "Streamer/%.*s/%.*s (percent)",
aznumeric_cast<int>(stat.GetOwner().length()), stat.GetOwner().data(), aznumeric_cast<int>(stat.GetName().length()), stat.GetName().data());
break;
default:
@@ -153,7 +153,7 @@ namespace AZ
bool StreamerContext::FinalizeCompletedRequests()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
#if AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
auto now = AZStd::chrono::system_clock::now();
@@ -218,10 +218,10 @@ namespace AZ
bool isInternal = top->m_usage == FileRequest::Usage::Internal;
{
AZ_PROFILE_SCOPE_STALL(AZ::Debug::ProfileCategory::AzCore,
AZ_PROFILE_SCOPE(AzCore,
isInternal ? "Completion callback internal" : "Completion callback external");
top->m_onCompletion(*top);
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::AzCore, top);
AZ_PROFILE_INTERVAL_END(AzCore, top);
}
if (parent)
@@ -9,7 +9,6 @@
#include <AzCore/IO/SystemFile.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/FileIOEventBus.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/PlatformIncl.h>
#include <AzCore/std/functional.h>
@@ -97,9 +96,6 @@ SystemFile& SystemFile::operator=(SystemFile&& other)
bool SystemFile::Open(const char* fileName, int mode, int platformFlags)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Open - %s", fileName);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Open - %s", fileName);
if (fileName) // If we reopen the file we are allowed to have NULL file name
{
if (strlen(fileName) > m_fileName.max_size())
@@ -136,9 +132,6 @@ bool SystemFile::ReOpen(int mode, int platformFlags)
void SystemFile::Close()
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Close - %s", m_fileName.c_str());
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Close - %s", m_fileName.c_str());
if (FileIOBus::HasHandlers())
{
bool isHandled = false;
@@ -154,8 +147,6 @@ void SystemFile::Close()
void SystemFile::Seek(SeekSizeType offset, SeekMode mode)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Seek - %s:%i", m_fileName.c_str(), offset);
if (FileIOBus::HasHandlers())
{
bool isHandled = false;
@@ -181,16 +172,11 @@ bool SystemFile::Eof()
AZ::u64 SystemFile::ModificationTime()
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime - %s", m_fileName.c_str());
return Platform::ModificationTime(m_handle, this);
}
SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read - %s:%i", m_fileName.c_str(), byteSize);
if (FileIOBus::HasHandlers())
{
SizeType numRead = 0;
@@ -207,9 +193,6 @@ SystemFile::SizeType SystemFile::Read(SizeType byteSize, void* buffer)
SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
{
AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory::AzCore, this, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Write - %s:%i", m_fileName.c_str(), byteSize);
if (FileIOBus::HasHandlers())
{
SizeType numWritten = 0;
@@ -226,15 +209,11 @@ SystemFile::SizeType SystemFile::Write(const void* buffer, SizeType byteSize)
void SystemFile::Flush()
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Flush - %s", m_fileName.c_str());
Platform::Flush(m_handle, this);
}
SystemFile::SizeType SystemFile::Length() const
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length - %s", m_fileName.c_str());
return Platform::Length(m_handle, this);
}
@@ -253,36 +232,26 @@ SystemFile::SizeType SystemFile::DiskOffset() const
bool SystemFile::Exists(const char* fileName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Exists(util) - %s", fileName);
return Platform::Exists(fileName);
}
void SystemFile::FindFiles(const char* filter, FindFileCB cb)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::FindFiles(util) - %s", filter);
Platform::FindFiles(filter, cb);
}
AZ::u64 SystemFile::ModificationTime(const char* fileName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::ModTime(util) - %s", fileName);
return Platform::ModificationTime(fileName);
}
SystemFile::SizeType SystemFile::Length(const char* fileName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Length(util) - %s", fileName);
return Platform::Length(fileName);
}
SystemFile::SizeType SystemFile::Read(const char* fileName, void* buffer, SizeType byteSize, SizeType byteOffset)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Read(util) - %s:[%i,%i]", fileName, byteOffset, byteSize);
SizeType numBytesRead = 0;
SystemFile f;
if (f.Open(fileName, SF_OPEN_READ_ONLY))
@@ -305,8 +274,6 @@ SystemFile::SizeType SystemFile::Read(const char* fileName, void* buffer, SizeTy
bool SystemFile::Delete(const char* fileName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Delete(util) - %s", fileName);
if (!Exists(fileName))
{
return false;
@@ -317,8 +284,6 @@ bool SystemFile::Delete(const char* fileName)
bool SystemFile::Rename(const char* sourceFileName, const char* targetFileName, bool overwrite)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::Rename(util) - %s", sourceFileName);
if (!Exists(sourceFileName))
{
return false;
@@ -329,29 +294,21 @@ bool SystemFile::Rename(const char* sourceFileName, const char* targetFileName,
bool SystemFile::IsWritable(const char* sourceFileName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::IsWritable(util) - %s", sourceFileName);
return Platform::IsWritable(sourceFileName);
}
bool SystemFile::SetWritable(const char* sourceFileName, bool writable)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::SetWritable(util) - %s", sourceFileName);
return Platform::SetWritable(sourceFileName, writable);
}
bool SystemFile::CreateDir(const char* dirName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::CreateDir(util) - %s", dirName);
return Platform::CreateDir(dirName);
}
bool SystemFile::DeleteDir(const char* dirName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::DeleteDir(util) - %s", dirName);
return Platform::DeleteDir(dirName);
}
@@ -23,10 +23,10 @@ void JobManagerBase::Process(Job* job)
Job* dependent = job->GetDependent();
bool isDelete = job->IsAutoDelete();
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::JobManagerDetailed, job);
AZ_PROFILE_INTERVAL_END(JobManagerDetailed, job);
if (!job->IsCancelled())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "AZ::JobManagerBase::Process Job");
AZ_PROFILE_SCOPE(AzCore, "AZ::JobManagerBase::Process Job");
job->Process();
}
@@ -122,7 +122,7 @@ void JobManagerWorkStealing::AddPendingJob(Job* job)
}
#endif
AZ_PROFILE_INTERVAL_START(AZ::Debug::ProfileCategory::JobManagerDetailed, job, "AzCore Job Queued Awaiting Execute");
AZ_PROFILE_INTERVAL_START(JobManagerDetailed, job, "AzCore Job Queued Awaiting Execute");
if (job->IsCompletion())
{
@@ -371,7 +371,7 @@ void JobManagerWorkStealing::ProcessJobsInternal(ThreadInfo* info, Job* suspende
{
//no available work, so go to sleep (or we have already been signaled by another thread and will acquire the semaphore but not actually sleep)
info->m_waitEvent.acquire();
AZ_PROFILE_INTERVAL_END(AZ::Debug::ProfileCategory::JobManagerDetailed, info);
AZ_PROFILE_INTERVAL_END(JobManagerDetailed, info);
if (m_quitRequested)
{
@@ -457,7 +457,7 @@ void JobManagerWorkStealing::ProcessJobsInternal(ThreadInfo* info, Job* suspende
else
{
//attempt to steal a job from another thread's queue
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "JobManagerWorkStealing::ProcessJobsInternal:WorkStealing");
AZ_PROFILE_SCOPE(AzCore, "JobManagerWorkStealing::ProcessJobsInternal:WorkStealing");
unsigned int numStealAttempts = 0;
const unsigned int maxStealAttempts = (unsigned int)m_workerThreads.size() * 3; //try every thread a few times before giving up
@@ -674,7 +674,7 @@ inline void JobManagerWorkStealing::ActivateWorker()
m_numAvailableWorkers.fetch_sub(1, AZStd::memory_order_acq_rel);
// resume the thread execution
AZ_PROFILE_INTERVAL_START(AZ::Debug::ProfileCategory::JobManagerDetailed, info, "AzCore WakeJobThread %d", info->m_workerId);
AZ_PROFILE_INTERVAL_START(JobManagerDetailed, info, "AzCore WakeJobThread %d", info->m_workerId);
info->m_waitEvent.release();
return;
}
@@ -33,7 +33,7 @@ namespace AZ
*/
void StartAndWaitForCompletion()
{
AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// start the job
Start();
@@ -72,7 +72,7 @@ namespace AZ
while (m_running)
{
AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
m_completionCondition.wait(uniqueLock, [this] { return !this->m_running; });
}
}
@@ -11,6 +11,7 @@
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Driller/DrillerBus.h>
#include <AzCore/std/time.h>
#include <AzCore/std/parallel/mutex.h>
#include <AzCore/Debug/StackTracer.h>
@@ -12,9 +12,7 @@
#include <AzCore/std/typetraits/aligned_storage.h>
#include <AzCore/std/typetraits/alignment_of.h>
#include <AzCore/Memory/AllocatorBase.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Memory/AllocatorBase.h>
#include <AzCore/Debug/MemoryProfiler.h>
namespace AZ
{
@@ -82,7 +80,7 @@ namespace AZ
if (ProfileAllocations)
{
AZ_PROFILE_MEMORY_ALLOC_EX(AZ::Debug::ProfileCategory::MemoryReserved, fileName, lineNum, ptr, byteSize, name ? name : GetName());
AZ_PROFILE_MEMORY_ALLOC_EX(MemoryReserved, fileName, lineNum, ptr, byteSize, name ? name : GetName());
AZ_MEMORY_PROFILE(ProfileAllocation(ptr, byteSize, alignment, name, fileName, lineNum, suppressStackRecord));
}
@@ -102,7 +100,7 @@ namespace AZ
if (ProfileAllocations)
{
AZ_PROFILE_MEMORY_FREE(AZ::Debug::ProfileCategory::MemoryReserved, ptr);
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
AZ_MEMORY_PROFILE(ProfileDeallocation(ptr, byteSize, alignment, nullptr));
}
@@ -128,7 +126,7 @@ namespace AZ
{
if (ProfileAllocations)
{
AZ_PROFILE_MEMORY_FREE(AZ::Debug::ProfileCategory::MemoryReserved, ptr);
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
}
newSize = MemorySizeAdjustedUp(newSize);
@@ -142,7 +140,7 @@ namespace AZ
if (ProfileAllocations)
{
AZ_PROFILE_MEMORY_ALLOC(AZ::Debug::ProfileCategory::MemoryReserved, newPtr, newSize, GetName());
AZ_PROFILE_MEMORY_ALLOC(MemoryReserved, newPtr, newSize, GetName());
AZ_MEMORY_PROFILE(ProfileReallocationEnd(ptr, newPtr, newSize, newAlignment));
}
@@ -260,7 +260,7 @@ SystemAllocator::Allocate(size_type byteSize, size_type alignment, int flags, co
AZ_Assert(address != 0, "SystemAllocator: Failed to allocate %d bytes aligned on %d (flags: 0x%08x) %s : %s (%d)!", byteSize, alignment, flags, name ? name : "(no name)", fileName ? fileName : "(no file name)", lineNum);
AZ_PROFILE_MEMORY_ALLOC_EX(AZ::Debug::ProfileCategory::MemoryReserved, fileName, lineNum, address, byteSize, name);
AZ_PROFILE_MEMORY_ALLOC_EX(MemoryReserved, fileName, lineNum, address, byteSize, name);
AZ_MEMORY_PROFILE(ProfileAllocation(address, byteSize, alignment, name, fileName, lineNum, suppressStackRecord + 1));
return address;
@@ -274,7 +274,7 @@ void
SystemAllocator::DeAllocate(pointer_type ptr, size_type byteSize, size_type alignment)
{
byteSize = MemorySizeAdjustedUp(byteSize);
AZ_PROFILE_MEMORY_FREE(AZ::Debug::ProfileCategory::MemoryReserved, ptr);
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
AZ_MEMORY_PROFILE(ProfileDeallocation(ptr, byteSize, alignment, nullptr));
m_allocator->DeAllocate(ptr, byteSize, alignment);
}
@@ -289,9 +289,9 @@ SystemAllocator::ReAllocate(pointer_type ptr, size_type newSize, size_type newAl
newSize = MemorySizeAdjustedUp(newSize);
AZ_MEMORY_PROFILE(ProfileReallocationBegin(ptr, newSize));
AZ_PROFILE_MEMORY_FREE(AZ::Debug::ProfileCategory::MemoryReserved, ptr);
AZ_PROFILE_MEMORY_FREE(MemoryReserved, ptr);
pointer_type newAddress = m_allocator->ReAllocate(ptr, newSize, newAlignment);
AZ_PROFILE_MEMORY_ALLOC(AZ::Debug::ProfileCategory::MemoryReserved, newAddress, newSize, "SystemAllocator realloc");
AZ_PROFILE_MEMORY_ALLOC(MemoryReserved, newAddress, newSize, "SystemAllocator realloc");
AZ_MEMORY_PROFILE(ProfileReallocationEnd(ptr, newAddress, newSize, newAlignment));
return newAddress;
+11 -8
View File
@@ -9,7 +9,6 @@
#define AZCORE_MODULE_INCLUDE_H 1
#include <AzCore/Component/Component.h>
#include <AzCore/Debug/ProfileModuleInit.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Module/Environment.h>
#include <AzCore/Interface/Interface.h>
@@ -78,9 +77,6 @@ namespace AZ
protected:
AZStd::list<AZ::ComponentDescriptor*> m_descriptors;
private:
AZ::Debug::ProfileModuleInitializer m_moduleProfilerInit;
};
} // namespace AZ
@@ -98,19 +94,26 @@ namespace AZ
///
/// \param MODULE_NAME Name of module.
/// \param MODULE_CLASSNAME Name of AZ::Module class (include namespace).
///
/// Execute any deferred console commands after linking any new deferred functors
/// This allows deferred console commands defined within the module to now execute
/// at this point now that the module has been loaded
#if defined(AZ_MONOLITHIC_BUILD)
# define AZ_DECLARE_MODULE_CLASS(MODULE_NAME, MODULE_CLASSNAME) \
extern "C" AZ::Module * CreateModuleClass_##MODULE_NAME() { return aznew MODULE_CLASSNAME; }
#else
# define AZ_DECLARE_MODULE_CLASS(MODULE_NAME, MODULE_CLASSNAME) \
AZ_DECLARE_MODULE_INITIALIZATION \
extern "C" AZ_DLL_EXPORT AZ::Module * CreateModuleClass() \
extern "C" AZ_DLL_EXPORT AZ::Module* CreateModuleClass() \
{ \
AZ::ConsoleFunctorBase*& deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead(); \
AZ::Interface<AZ::IConsole>::Get()->LinkDeferredFunctors(deferredHead); \
if (auto console = AZ::Interface<AZ::IConsole>::Get(); console != nullptr) \
{ \
console->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead()); \
console->ExecuteDeferredConsoleCommands(); \
} \
return aznew MODULE_CLASSNAME; \
} \
extern "C" AZ_DLL_EXPORT void DestroyModuleClass(AZ::Module * module) { delete module; }
extern "C" AZ_DLL_EXPORT void DestroyModuleClass(AZ::Module* module) { delete module; }
#endif
#endif // AZCORE_MODULE_INCLUDE_H
@@ -287,14 +287,6 @@ void ScriptSystemComponent::OnSystemTick()
contextContainer.m_context->GetDebugContext()->ProcessDebugCommands();
}
#ifdef AZ_PROFILE_TELEMETRY
if (contextContainer.m_context->GetId() == ScriptContextIds::DefaultScriptContextId)
{
size_t memoryUsageBytes = contextContainer.m_context->GetMemoryUsage();
AZ_PROFILE_DATAPOINT(AZ::Debug::ProfileCategory::Script, memoryUsageBytes / 1024.0, "Script Memory (KB)");
}
#endif // AZ_PROFILE_TELEMETRY
contextContainer.m_context->GarbageCollectStep(contextContainer.m_garbageCollectorSteps);
}
}
@@ -143,7 +143,7 @@ namespace AZ
//=========================================================================
void DataNodeTree::Build(const void* rootClassPtr, const Uuid& rootClassId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
m_root.Reset();
m_currentNode = nullptr;
@@ -1400,7 +1400,7 @@ namespace AZ
AddressTypeElement AddressTypeSerializer::LoadAddressElementFromPath(const AZStd::string& pathElement) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// AddressTypeElement default constructor defaults to an invalid addressElement
AddressTypeElement addressElement;
@@ -1485,13 +1485,13 @@ namespace AZ
/// Load the class data from a stream.
bool AddressTypeSerializer::Load(void* classPtr, IO::GenericStream& stream, unsigned int version, bool isDataBigEndian /*= false*/)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
(void)isDataBigEndian;
constexpr unsigned int version1PathAddress = 1;
if (version < version1PathAddress)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "AddressTypeSerializer::Load::LegacyUpgrade");
AZ_PROFILE_SCOPE(AzCore, "AddressTypeSerializer::Load::LegacyUpgrade");
// Grab the AddressType object to be filled
AddressType* address = reinterpret_cast<AddressType*>(classPtr);
address->clear();
@@ -1516,7 +1516,7 @@ namespace AZ
}
else
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "AddressTypeSerializer::Load::CurrentFlow");
AZ_PROFILE_SCOPE(AzCore, "AddressTypeSerializer::Load::CurrentFlow");
// Grab the AddressType object to be filled
AddressType* address = reinterpret_cast<AddressType*>(classPtr);
address->clear();
@@ -1749,7 +1749,7 @@ namespace AZ
const FlagsMap& targetFlagsMap,
SerializeContext* context)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!source || !target)
{
@@ -1804,7 +1804,7 @@ namespace AZ
targetTree.Build(target, targetClassId);
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "DataPatch::Create:RecursiveCallToCompareElements");
AZ_PROFILE_SCOPE(AzCore, "DataPatch::Create:RecursiveCallToCompareElements");
sourceTree.CompareElements(
&sourceTree.m_root,
@@ -1829,7 +1829,7 @@ namespace AZ
const FlagsMap& sourceFlagsMap,
const FlagsMap& targetFlagsMap) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!source)
{
@@ -1870,7 +1870,7 @@ namespace AZ
{
// Loop over the original data patch and make a copy of the key value pair
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "DataPatch::Apply:UpgradeDataPatch");
AZ_PROFILE_SCOPE(AzCore, "DataPatch::Apply:UpgradeDataPatch");
// Copy of the patch element is purposefully being created here(notice no ampersand) so that the UpgradeDataPatch
// function can modify the key and insert it into the fixed patch map
for (PatchMap::value_type patch : m_patch)
@@ -1883,7 +1883,7 @@ namespace AZ
// Build a mapping of child patches for quick look-up: [parent patch address] -> [list of patches for child elements (parentAddress + one more address element)]
ChildPatchMap childPatchMap;
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "DataPatch::Apply:GenerateChildPatchMap");
AZ_PROFILE_SCOPE(AzCore, "DataPatch::Apply:GenerateChildPatchMap");
for (auto& patch : fixedPatch)
{
AddressType parentAddress = patch.first;
@@ -1921,7 +1921,7 @@ namespace AZ
}
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "DataPatch::Apply:RecursiveCallToApplyToElements");
AZ_PROFILE_SCOPE(AzCore, "DataPatch::Apply:RecursiveCallToApplyToElements");
int rootContainerElementCounter = 0;
result = DataNodeTree::ApplyToElements(
@@ -2015,7 +2015,7 @@ namespace AZ
*/
bool LegacyDataPatchConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ::Outcome<void, AZStd::string> conversionResult = LegacyDataPatchConverter_Impl(context, classElement);
if (!conversionResult.IsSuccess())
@@ -2043,7 +2043,7 @@ namespace AZ
*/
AZ::Outcome<void, AZStd::string> LegacyDataPatchConverter_Impl(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Pull the targetClassId value out of the class element before it gets cleared when converting the DataPatch TypeId
AZ::TypeId targetClassTypeId;
if (!classElement.GetChildData(AZ_CRC("m_targetClassId", 0xcabab9dc), targetClassTypeId))
@@ -786,7 +786,7 @@ namespace AZ
// Serializable leaf element.
else if (classData->m_serializer)
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "ObjectStreamImpl::LoadClass Load");
AZ_PROFILE_SCOPE(AzCore, "ObjectStreamImpl::LoadClass Load");
// Wrap the stream
IO::GenericStream* currentStream = &m_inStream;
@@ -1929,7 +1929,7 @@ namespace AZ
//=========================================================================
bool ObjectStreamImpl::Start()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
++m_pending;
@@ -24,7 +24,7 @@ namespace AZ
{
bool LoadObjectFromStreamInPlace(IO::GenericStream& stream, AZ::SerializeContext* context, const SerializeContext::ClassData* objectClassData, void* targetPointer, const FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(objectClassData, "Class data is required.");
@@ -72,7 +72,7 @@ namespace AZ
bool LoadObjectFromStreamInPlace(IO::GenericStream& stream, AZ::SerializeContext* context, const Uuid& targetClassId, void* targetPointer, const FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!context)
{
@@ -111,7 +111,7 @@ namespace AZ
void* LoadObjectFromStream(IO::GenericStream& stream, AZ::SerializeContext* context, const Uuid* targetClassId, const FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!context)
{
@@ -169,7 +169,7 @@ namespace AZ
void* LoadObjectFromFile(const AZStd::string& filePath, const Uuid& targetClassId, SerializeContext* context, const FilterDescriptor& filterDesc, int /*platformFlags*/)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ::IO::FileIOStream fileStream;
if (!fileStream.Open(filePath.c_str(), IO::OpenMode::ModeRead | IO::OpenMode::ModeBinary))
@@ -183,7 +183,7 @@ namespace AZ
bool SaveObjectToStream(IO::GenericStream& stream, DataStream::StreamType streamType, const void* classPtr, const Uuid& classId, SerializeContext* context, const SerializeContext::ClassData* classData)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!context)
{
@@ -243,7 +243,7 @@ namespace AZ
bool SaveObjectToFile(const AZStd::string& filePath, DataStream::StreamType fileType, const void* classPtr, const Uuid& classId, SerializeContext* context, int platformFlags)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// \note This is ok for tools, but we should use the streamer to write objects directly (no memory store)
AZStd::vector<AZ::u8> dstData;
@@ -198,7 +198,7 @@ namespace AZ
const EntityIdToEntityIdMap* remapFromIdToId/*=nullptr*/,
const DataFlagsTransformFunction& dataFlagsTransformFn/*=nullptr*/)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
for (const auto& entityIdFlagsMapPair : from.m_entityToDataFlags)
{
@@ -240,7 +240,7 @@ namespace AZ
//=========================================================================
DataPatch::FlagsMap SliceComponent::DataFlagsPerEntity::GetDataFlagsForPatching(const EntityIdToEntityIdMap* remapFromIdToId /*=nullptr*/) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Collect together data flags from all entities
DataPatch::FlagsMap dataFlagsForAllEntities;
@@ -423,7 +423,7 @@ namespace AZ
//=========================================================================
void SliceComponent::DataFlagsPerEntity::Cleanup(const EntityList& validEntities)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
EntityIdSet validEntityIds;
for (const Entity* entity : validEntities)
@@ -677,7 +677,7 @@ namespace AZ
//=========================================================================
SliceComponent::SliceInstance* SliceComponent::SliceReference::PrepareCreateInstance(const SliceInstanceId& sliceInstanceId, bool allowUninstantiated)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// create an empty instance (just copy of the existing data)
SliceInstance* instance = CreateEmptyInstance(sliceInstanceId);
@@ -737,7 +737,7 @@ namespace AZ
AZ::SerializeContext* serializeContext,
const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper& customMapper)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!remapContainer)
{
@@ -808,7 +808,7 @@ namespace AZ
SliceComponent::SliceInstance* SliceComponent::SliceReference::CreateInstance(const AZ::IdUtils::Remapper<AZ::EntityId>::IdMapper& customMapper,
SliceInstanceId sliceInstanceId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Validate that we are able to create an instance at this time
// If we are instantiated then this includes verifying that we have a valid component and asset
@@ -842,7 +842,7 @@ namespace AZ
const EntityIdToEntityIdMap assetToLiveIdMap,
SliceInstanceId sliceInstanceId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Validate that we are able to create an instance at this time
// This includes verifying that we are instantiated, and have a valid component and asset
@@ -883,7 +883,7 @@ namespace AZ
SliceComponent::SliceInstance* SliceComponent::SliceReference::CloneInstance(SliceComponent::SliceInstance* instance,
SliceComponent::EntityIdToEntityIdMap& sourceToCloneEntityIdMap)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// check if source instance belongs to this slice reference
auto findIt = AZStd::find_if(m_instances.begin(), m_instances.end(), [instance](const SliceInstance& element) -> bool { return &element == instance; });
@@ -1053,7 +1053,7 @@ namespace AZ
//=========================================================================
bool SliceComponent::SliceReference::Instantiate(const AZ::ObjectStream::FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (m_isInstantiated)
{
@@ -1145,7 +1145,7 @@ namespace AZ
//=========================================================================
void SliceComponent::SliceReference::InstantiateInstance(SliceInstance& instance, const AZ::ObjectStream::FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Could have set this during SliceInstance() constructor, but we wait until instantiation since it involves allocation.
instance.m_dataFlags.SetIsValidEntityFunction([&instance](EntityId entityId) { return instance.IsValidEntity(entityId); });
@@ -1167,7 +1167,7 @@ namespace AZ
// An empty map indicates its a fresh instance (i.e. has never be instantiated and then serialized).
if (entityIdMap.empty())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "SliceComponent::SliceReference::InstantiateInstance:FreshInstanceClone");
AZ_PROFILE_SCOPE(AzCore, "SliceComponent::SliceReference::InstantiateInstance:FreshInstanceClone");
// Generate new Ids and populate the map.
AZ_Assert(!dataPatch.IsValid(), "Data patch is valid for slice instance, but entity Id map is not!");
@@ -1175,7 +1175,7 @@ namespace AZ
}
else
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "SliceComponent::SliceReference::InstantiateInstance:CloneAndApplyDataPatches");
AZ_PROFILE_SCOPE(AzCore, "SliceComponent::SliceReference::InstantiateInstance:CloneAndApplyDataPatches");
// Clone entities while applying any data patches.
AZ_Assert(dataPatch.IsValid(), "Data patch is not valid for existing slice instance!");
@@ -1261,7 +1261,7 @@ namespace AZ
// Broadcast OnSliceEntitiesLoaded for freshly instantiated entities.
if (!instance.m_instantiated->m_entities.empty())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "SliceComponent::SliceReference::InstantiateInstance:OnSliceEntitiesLoaded");
AZ_PROFILE_SCOPE(AzCore, "SliceComponent::SliceReference::InstantiateInstance:OnSliceEntitiesLoaded");
SliceAssetSerializationNotificationBus::Broadcast(&SliceAssetSerializationNotificationBus::Events::OnSliceEntitiesLoaded, instance.m_instantiated->m_entities);
}
}
@@ -1363,7 +1363,7 @@ namespace AZ
//=========================================================================
void SliceComponent::SliceReference::ComputeDataPatch()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// Get source entities from the base asset (instantiate if needed)
InstantiatedContainer source(m_asset.Get()->GetComponent(), false);
@@ -1499,7 +1499,7 @@ namespace AZ
//=========================================================================
bool SliceComponent::GetEntities(EntityList& entities)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
bool result = true;
@@ -1532,7 +1532,7 @@ namespace AZ
//=========================================================================
bool SliceComponent::GetEntityIds(EntityIdSet& entities)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
bool result = true;
@@ -1582,7 +1582,7 @@ namespace AZ
//=========================================================================
bool SliceComponent::GetMetadataEntityIds(EntityIdSet& metadataEntities)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
bool result = true;
@@ -1654,7 +1654,7 @@ namespace AZ
//=========================================================================
SliceComponent::InstantiateResult SliceComponent::Instantiate()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZStd::unique_lock<AZStd::recursive_mutex> lock(m_instantiateMutex);
if (m_slicesAreInstantiated)
@@ -1856,7 +1856,7 @@ namespace AZ
SliceComponent::SliceInstanceAddress SliceComponent::AddSliceUsingExistingEntities(const Data::Asset<SliceAsset>& sliceAsset, const AZ::SliceComponent::EntityIdToEntityIdMap& liveToAssetMap,
SliceInstanceId sliceInstanceId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!sliceAsset.Get()->GetComponent())
{
@@ -2337,7 +2337,7 @@ namespace AZ
//=========================================================================
bool SliceComponent::RemoveSliceInstance(SliceComponent::SliceInstanceAddress sliceAddress)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!sliceAddress.IsValid())
{
AZ_Error("Slices", false, "Slice address is invalid.");
@@ -2474,7 +2474,7 @@ namespace AZ
bool SliceComponent::RemoveMetaDataEntity(EntityId metaDataEntityId)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
GetEntityInfoMap(); // Ensure map is built
@@ -2567,7 +2567,7 @@ namespace AZ
void SliceComponent::RemoveAllEntities(bool deleteEntities, bool removeEmptyInstances)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
// If we are deleting the entities, we need to do that one by one
if (deleteEntities)
@@ -2930,7 +2930,7 @@ namespace AZ
//=========================================================================
void SliceComponent::OnAssetReloaded(Data::Asset<Data::AssetData> /*asset*/)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!m_myAsset)
{
@@ -3073,7 +3073,7 @@ namespace AZ
/// Called right after we finish writing data to the instance pointed at by classPtr.
void OnWriteEnd(void* classPtr) override
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
SliceComponent* sliceComponent = reinterpret_cast<SliceComponent*>(classPtr);
EBUS_EVENT(SliceAssetSerializationNotificationBus, OnWriteDataToSliceAssetEnd, *sliceComponent);
@@ -3082,7 +3082,7 @@ namespace AZ
// We can't broadcast this event for instanced entities yet, since they don't exist until instantiation.
if (!sliceComponent->GetNewEntities().empty())
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "SliceComponentSerializationEvents::OnWriteEnd:OnSliceEntitiesLoaded");
AZ_PROFILE_SCOPE(AzCore, "SliceComponentSerializationEvents::OnWriteEnd:OnSliceEntitiesLoaded");
EBUS_EVENT(SliceAssetSerializationNotificationBus, OnSliceEntitiesLoaded, sliceComponent->GetNewEntities());
}
}
@@ -3093,7 +3093,7 @@ namespace AZ
//=========================================================================
void SliceComponent::PrepareSave()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (m_slicesAreInstantiated)
{
@@ -3262,7 +3262,7 @@ namespace AZ
//=========================================================================
void SliceComponent::BuildEntityInfoMap()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
m_entityInfoMap.clear();
m_metaDataEntityInfoMap.clear();
@@ -3425,7 +3425,7 @@ namespace AZ
//=========================================================================
void SliceComponent::BuildDataFlagsForInstances()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(IsInstantiated(), "Slice must be instantiated before the ancestry of its data flags can be calculated.");
// Use lock since slice instantiation can occur from multiple threads
@@ -3551,7 +3551,7 @@ namespace AZ
{
// if this function is a performance bottleneck, it could be optimized with caching
// be wary not to create the cache in-game if the information is only needed by tools
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!IsInstantiated())
{
@@ -3730,7 +3730,7 @@ namespace AZ
//=========================================================================
SliceComponent* SliceComponent::Clone(AZ::SerializeContext& serializeContext, SliceInstanceToSliceInstanceMap* sourceToCloneSliceInstanceMap) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
SliceComponent* clonedComponent = serializeContext.CloneObject(this);
@@ -17,154 +17,148 @@
#include <AzCore/Debug/Profiler.h>
#if !defined(AZ_PROFILE_TELEMETRY) && defined(AZ_STATISTICAL_PROFILING_ENABLED)
#if defined(AZ_STATISTICAL_PROFILING_ENABLED)
#if defined(AZ_PROFILE_SCOPE)
#undef AZ_PROFILE_SCOPE
#endif // #if defined(AZ_PROFILE_SCOPE)
#define AZ_PROFILE_SCOPE(profiler, scopeNameId) \
static_assert(profiler < AZ::Debug::ProfileCategory::Count, "Invalid profiler category"); \
static const AZStd::string AZ_JOIN(blockName, __LINE__)(scopeNameId); \
AZ::Statistics::StatisticalProfilerProxy::TimedScope AZ_JOIN(scope, __LINE__)(profiler, AZ_JOIN(blockName, __LINE__));
#endif //#if !defined(AZ_PROFILE_TELEMETRY)
#endif //#if defined(AZ_STATISTICAL_PROFILING_ENABLED)
namespace AZ
namespace AZ::Statistics
{
namespace Statistics
{
using StatisticalProfilerId = AZ::Debug::ProfileCategory;
using StatisticalProfilerId = uint32_t;
//! This AZ::Interface<> (Yes, it is an application wide singleton) owns an array of StatisticalProfilers.
//! When is this useful?
//! When you need to statistically profile code that runs across DLL boundaries.
//!
//! What is the meaning of "statistically profile" code?
//! In regular profiling with tools like RAD Telemetry, every execution of a profiled
//! scope of code will be captured when using AZ_PROFILE_SCOPE(). You can collect
//! very large amounts of data and do your own post processing and analysis in tools like Excel,etc.
//! In contrast, "statistical profiling" means that everytime AZ_PROFILE_SCOPE() is called,
//! the time spent in the given scope of code will be mathematically accumulated as part of a unique
//! Running statistic. Common statistical parameters like min, max, average, variance and standard deviation
//! are calculated on the fly. This approach reduces considerably the amount of data that is collected.
//! The data is recorded in the Game/Editor Log file.
//!
//! This StatisticalProfilerProxy should be used via the AZ_PROFILE_SCOPE() macro, and by using
//! this macro the developer gains the flexibility of switching at compile time between profiling
//! the code via RAD Telemetry or through statistical profiling.
//!
//! When creating a new statistical profiler add your category (aka profiler id) in Profiler.h (enum class ProfileCategory).
//! Get a reference of the statistical profiler with "GetProfiler(const StatisticalProfilerId& id)" using the profiler Id.
//! Once you get a reference to the profiler you can customize it, add Running statistics to it, etc.
//! Some class in your code will manage the reference to the statistical profiler and will determine
//! the policy on how often to log data to the game logs, etc. For example, by subclassing the TickBus Handler, etc.
//!
//! The StatisticalProfilerProxySystemComponent guarantees that the StatisticalProfilerProxy singleton exists
//! as soon as the AZ::Environment is fully initialized.
//! See StatisticalProfiler.h for more details and info.
class StatisticalProfilerProxy
//! This AZ::Interface<> (Yes, it is an application wide singleton) owns an array of StatisticalProfilers.
//! When is this useful?
//! When you need to statistically profile code that runs across DLL boundaries.
//!
//! What is the meaning of "statistically profile" code?
//! In regular profiling with tools like RAD Telemetry, every execution of a profiled
//! scope of code will be captured when using AZ_PROFILE_SCOPE(). You can collect
//! very large amounts of data and do your own post processing and analysis in tools like Excel,etc.
//! In contrast, "statistical profiling" means that everytime AZ_PROFILE_SCOPE() is called,
//! the time spent in the given scope of code will be mathematically accumulated as part of a unique
//! Running statistic. Common statistical parameters like min, max, average, variance and standard deviation
//! are calculated on the fly. This approach reduces considerably the amount of data that is collected.
//! The data is recorded in the Game/Editor Log file.
//!
//! This StatisticalProfilerProxy should be used via the AZ_PROFILE_SCOPE() macro, and by using
//! this macro the developer gains the flexibility of switching at compile time between profiling
//! the code via RAD Telemetry or through statistical profiling.
//!
//! When creating a new statistical profiler add your category (aka profiler id) in Profiler.h (enum class ProfileCategory).
//! Get a reference of the statistical profiler with "GetProfiler(const StatisticalProfilerId& id)" using the profiler Id.
//! Once you get a reference to the profiler you can customize it, add Running statistics to it, etc.
//! Some class in your code will manage the reference to the statistical profiler and will determine
//! the policy on how often to log data to the game logs, etc. For example, by subclassing the TickBus Handler, etc.
//!
//! The StatisticalProfilerProxySystemComponent guarantees that the StatisticalProfilerProxy singleton exists
//! as soon as the AZ::Environment is fully initialized.
//! See StatisticalProfiler.h for more details and info.
class StatisticalProfilerProxy
{
public:
AZ_TYPE_INFO(StatisticalProfilerProxy, "{1103D0EB-1C32-4854-B9D9-40A2D65BDBD2}");
using StatIdType = AZStd::string;
using StatisticalProfilerType = StatisticalProfiler<StatIdType, AZStd::shared_spin_mutex>;
//! A Convenience class used to measure time performance of scopes of code
//! with constructor/destructor. Suitable to be used as part of a macro
//! to facilitate its usage.
class TimedScope
{
public:
AZ_TYPE_INFO(StatisticalProfilerProxy, "{1103D0EB-1C32-4854-B9D9-40A2D65BDBD2}");
TimedScope() = delete;
using StatIdType = AZStd::string;
using StatisticalProfilerType = StatisticalProfiler<StatIdType, AZStd::shared_spin_mutex>;
//! A Convenience class used to measure time performance of scopes of code
//! with constructor/destructor. Suitable to be used as part of a macro
//! to facilitate its usage.
class TimedScope
TimedScope(const StatisticalProfilerId profilerId, const StatIdType& statId)
: m_profilerId(profilerId)
, m_statId(statId)
{
public:
TimedScope() = delete;
TimedScope(const StatisticalProfilerId profilerId, const StatIdType& statId)
: m_profilerId(profilerId), m_statId(statId)
{
if (!m_profilerProxy)
{
m_profilerProxy = AZ::Interface<StatisticalProfilerProxy>::Get();
if (!m_profilerProxy)
{
return;
}
}
if (!m_profilerProxy->IsProfilerActive(profilerId))
{
return;
}
m_startTime = AZStd::chrono::high_resolution_clock::now();
}
~TimedScope()
if (!m_profilerProxy)
{
m_profilerProxy = AZ::Interface<StatisticalProfilerProxy>::Get();
if (!m_profilerProxy)
{
return;
}
AZStd::chrono::system_clock::time_point stopTime = AZStd::chrono::high_resolution_clock::now();
AZStd::chrono::microseconds duration = stopTime - m_startTime;
m_profilerProxy->PushSample(m_profilerId, m_statId, static_cast<double>(duration.count()));
}
//! Required only for UnitTests
static void ClearCachedProxy()
if (!m_profilerProxy->IsProfilerActive(profilerId))
{
m_profilerProxy = nullptr;
return;
}
private:
static StatisticalProfilerProxy* m_profilerProxy;
const StatisticalProfilerId m_profilerId;
const StatIdType& m_statId;
AZStd::chrono::system_clock::time_point m_startTime;
}; //class TimedScope
friend class TimedScope;
StatisticalProfilerProxy()
m_startTime = AZStd::chrono::high_resolution_clock::now();
}
~TimedScope()
{
m_profilers.reserve(static_cast<AZStd::size_t>(AZ::Debug::ProfileCategory::Count));
for (AZStd::size_t i = 0; i < static_cast<AZStd::size_t>(AZ::Debug::ProfileCategory::Count); i++)
if (!m_profilerProxy)
{
m_profilers.emplace_back(StatisticalProfilerType());
return;
}
AZ::Interface<StatisticalProfilerProxy>::Register(this);
AZStd::chrono::system_clock::time_point stopTime = AZStd::chrono::high_resolution_clock::now();
AZStd::chrono::microseconds duration = stopTime - m_startTime;
m_profilerProxy->PushSample(m_profilerId, m_statId, static_cast<double>(duration.count()));
}
virtual ~StatisticalProfilerProxy()
//! Required only for UnitTests
static void ClearCachedProxy()
{
AZ::Interface<StatisticalProfilerProxy>::Unregister(this);
}
// Note that you have to delete these for safety reasons, you will trip a static_assert if you do not
StatisticalProfilerProxy(StatisticalProfilerProxy&&) = delete;
StatisticalProfilerProxy& operator=(StatisticalProfilerProxy&&) = delete;
bool IsProfilerActive(StatisticalProfilerId id) const
{
return m_activeProfilersFlag[static_cast<AZStd::size_t>(id)];
}
StatisticalProfilerType& GetProfiler(StatisticalProfilerId id)
{
return m_profilers[static_cast<AZStd::size_t>(id)];
}
void ActivateProfiler(StatisticalProfilerId id, bool activate)
{
m_activeProfilersFlag[static_cast<AZStd::size_t>(id)] = activate;
}
void PushSample(StatisticalProfilerId id, const StatIdType& statId, double value)
{
m_profilers[static_cast<AZStd::size_t>(id)].PushSample(statId, value);
m_profilerProxy = nullptr;
}
private:
AZStd::bitset<static_cast<AZStd::size_t>(AZ::Debug::ProfileCategory::Count)> m_activeProfilersFlag;
AZStd::vector<StatisticalProfilerType> m_profilers;
}; //class StatisticalProfilerProxy
static StatisticalProfilerProxy* m_profilerProxy;
const StatisticalProfilerId m_profilerId;
const StatIdType& m_statId;
AZStd::chrono::system_clock::time_point m_startTime;
}; // class TimedScope
}; //namespace Statistics
}; //namespace AZ
friend class TimedScope;
StatisticalProfilerProxy()
{
// TODO:BUDGETS Query available budgets at registration time and create an associated profiler per type
AZ::Interface<StatisticalProfilerProxy>::Register(this);
}
virtual ~StatisticalProfilerProxy()
{
AZ::Interface<StatisticalProfilerProxy>::Unregister(this);
}
// Note that you have to delete these for safety reasons, you will trip a static_assert if you do not
StatisticalProfilerProxy(StatisticalProfilerProxy&&) = delete;
StatisticalProfilerProxy& operator=(StatisticalProfilerProxy&&) = delete;
bool IsProfilerActive(StatisticalProfilerId id) const
{
return m_activeProfilersFlag[static_cast<AZStd::size_t>(id)];
}
StatisticalProfilerType& GetProfiler(StatisticalProfilerId id)
{
return m_profilers[static_cast<AZStd::size_t>(id)];
}
void ActivateProfiler(StatisticalProfilerId id, bool activate)
{
m_activeProfilersFlag[static_cast<AZStd::size_t>(id)] = activate;
}
void PushSample(StatisticalProfilerId id, const StatIdType& statId, double value)
{
m_profilers[static_cast<AZStd::size_t>(id)].PushSample(statId, value);
}
private:
// TODO:BUDGETS the number of bits allocated here must be based on the number of budgets available at profiler registration time
AZStd::bitset<128> m_activeProfilersFlag;
AZStd::vector<StatisticalProfilerType> m_profilers;
}; // class StatisticalProfilerProxy
}; // namespace AZ::Statistics
@@ -99,8 +99,7 @@ set(FILES
Debug/FrameProfilerComponent.cpp
Debug/FrameProfilerComponent.h
Debug/IEventLogger.h
Debug/ProfileModuleInit.cpp
Debug/ProfileModuleInit.h
Debug/MemoryProfiler.h
Debug/Profiler.cpp
Debug/Profiler.h
Debug/ProfilerBus.h
@@ -8,7 +8,6 @@
#ifndef AZSTD_PARALLEL_SPIN_MUTEX_H
#define AZSTD_PARALLEL_SPIN_MUTEX_H 1
#include <AzCore/Debug/Profiler.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/std/parallel/exponential_backoff.h>
@@ -32,8 +31,6 @@ namespace AZStd
bool expected = false;
if (!m_flag.compare_exchange_weak(expected, true, memory_order_acq_rel, memory_order_acquire))
{
AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::AzCore);
exponential_backoff backoff;
for (;; )
{
+8 -9
View File
@@ -12,11 +12,10 @@
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common)
if(LY_RAD_TELEMETRY_ENABLED)
set(AZ_CORE_RADTELEMETRY_FILES ${common_dir}/azcore_profile_telemetry_files.cmake)
set(AZ_CORE_RADTELEMETRY_PLATFORM_INCLUDES ${pal_dir}/profile_telemetry_platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
set(AZ_CORE_RADTELEMETRY_INCLUDE_DIRECTORIES ${common_dir})
set(AZ_CORE_RADTELEMETRY_BUILD_DEPENDENCIES 3rdParty::RadTelemetry)
if(PAL_TRAIT_PROF_PIX_SUPPORTED AND LY_PIX_ENABLED)
set(LY_PIX_PATH "${LY_3RDPARTY_PATH}/winpixeventruntime" CACHE PATH "Path to the Windows Pix Event Runtime.")
set(AZ_CORE_PIX_BUILD_DEPENDENCIES 3rdParty::pix)
set(AZ_CORE_PIX_BUILD_DEFINES "USE_PIX")
endif()
ly_add_target(
@@ -26,16 +25,13 @@ ly_add_target(
AzCore/azcore_files.cmake
AzCore/std/azstd_files.cmake
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
${AZ_CORE_RADTELEMETRY_FILES}
PLATFORM_INCLUDE_FILES
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
${AZ_CORE_RADTELEMETRY_PLATFORM_INCLUDES}
INCLUDE_DIRECTORIES
PUBLIC
.
${pal_dir}
${common_dir}
${AZ_CORE_RADTELEMETRY_INCLUDE_DIRECTORIES}
BUILD_DEPENDENCIES
PUBLIC
3rdParty::Lua
@@ -44,7 +40,10 @@ ly_add_target(
3rdParty::zlib
3rdParty::zstd
3rdParty::cityhash
${AZ_CORE_RADTELEMETRY_BUILD_DEPENDENCIES}
${AZ_CORE_PIX_BUILD_DEPENDENCIES}
COMPILE_DEFINITIONS
PUBLIC
${AZ_CORE_PIX_BUILD_DEFINES}
)
ly_add_source_properties(
SOURCES
@@ -11,7 +11,3 @@
# NOTE: functions in cmake are global, therefore adding functions to this file
# is being avoided to prevent overriding functions declared in other targets platfrom
# specific cmake files
if(LY_RAD_TELEMETRY_ENABLED)
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
endif()
@@ -1,159 +0,0 @@
/*
* 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
#ifdef AZ_PROFILE_TELEMETRY
/*!
* ProfileTelemetry.h provides a RAD Telemetry specific implementation of the AZ_PROFILE_FUNCTION, AZ_PROFILE_SCOPE, and AZ_PROFILE_SCOPE_DYNAMIC performance instrumentation markers
*/
#define TM_API_PTR g_radTmApi
#include <rad_tm.h>
#include <AzCore/Math/Color.h>
namespace ProfileTelemetryInternal
{
inline constexpr tm_uint32 ConvertColor(uint32_t rgba)
{
return
((rgba >> 24) & 0x000000ff) | // move byte 3 to byte 0
((rgba << 8) & 0x00ff0000) | // move byte 1 to byte 2
((rgba >> 8) & 0x0000ff00) | // move byte 2 to byte 1
((rgba << 24) & 0xff000000); // byte 0 to byte 3
}
inline constexpr tm_uint32 ConvertColor(const AZ::Color& color)
{
return ConvertColor(color.ToU32());
}
}
#define AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category) (static_cast<AZ::Debug::ProfileCategoryPrimitiveType>(1) << static_cast<AZ::Debug::ProfileCategoryPrimitiveType>(category))
// Helpers
#define AZ_INTERNAL_PROF_VERIFY_CAT(category) static_assert(category < AZ::Debug::ProfileCategory::Count, "Invalid profile category")
#define AZ_INTERNAL_PROF_MEMORY_CAT_TO_FLAGS(category) (AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category) | \
AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(AZ::Debug::ProfileCategory::MemoryReserved))
#define AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id) static_assert(sizeof(id) <= sizeof(tm_uint64), "Interval id must be a unique value no larger than 64-bits")
#define AZ_INTERNAL_PROF_TM_FUNC_VERIFY_CAT(category, flags) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmFunction(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), flags)
#define AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, flags, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmZone(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), flags, __VA_ARGS__)
// AZ_PROFILE_FUNCTION
#define AZ_PROFILE_FUNCTION(category) \
AZ_INTERNAL_PROF_TM_FUNC_VERIFY_CAT(category, TMZF_NONE)
#define AZ_PROFILE_FUNCTION_STALL(category) \
AZ_INTERNAL_PROF_TM_FUNC_VERIFY_CAT(category, TMZF_STALL)
#define AZ_PROFILE_FUNCTION_IDLE(category) \
AZ_INTERNAL_PROF_TM_FUNC_VERIFY_CAT(category, TMZF_IDLE)
// AZ_PROFILE_SCOPE
#define AZ_PROFILE_SCOPE(category, name) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_NONE, name)
#define AZ_PROFILE_SCOPE_STALL(category, name) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_STALL, name)
#define AZ_PROFILE_SCOPE_IDLE(category, name) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_IDLE, name)
// AZ_PROFILE_SCOPE_DYNAMIC
// For profiling events with dynamic scope names
// Note: the first variable argument must be a const format string
// Usage: AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory, <printf style const format string>, format args...)
#define AZ_PROFILE_SCOPE_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_NONE, __VA_ARGS__)
#define AZ_PROFILE_SCOPE_STALL_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_STALL, __VA_ARGS__)
#define AZ_PROFILE_SCOPE_IDLE_DYNAMIC(category, ...) \
AZ_INTERNAL_PROF_TM_ZONE_VERIFY_CAT(category, TMZF_IDLE, __VA_ARGS__)
// AZ_PROFILE_EVENT_BEGIN/END
// For profiling events that do not start and stop in the same scope (they MUST start/stop on the same thread)
// ALWAYS favor using scoped events (AZ_PROFILE_FUNCTION, AZ_PROFILE_SCOPE) as debugging an unmatched begin/end can be challenging
#define AZ_PROFILE_EVENT_BEGIN(category, name) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmEnter(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), TMZF_NONE, name)
#define AZ_PROFILE_EVENT_END(category) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmLeave(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category))
// AZ_PROFILE_INTERVAL (mapped to Telemetry Timespan APIs)
// Note: using C-style casting as we allow either pointers or integral types as IDs
#define AZ_PROFILE_INTERVAL_START(category, id, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id); \
tmBeginTimeSpan(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), (tm_uint64)(id), TMZF_NONE, __VA_ARGS__)
#define AZ_PROFILE_INTERVAL_START_COLORED(category, id, color, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id); \
tmBeginColoredTimeSpan(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), (tm_uint64)(id), 0, ProfileTelemetryInternal::ConvertColor(color), TMZF_NONE, __VA_ARGS__)
#define AZ_PROFILE_INTERVAL_END(category, id) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id); \
tmEndTimeSpan(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), (tm_uint64)(id))
// AZ_PROFILE_INTERVAL_SCOPED
// Scoped interval event that implicitly starts and ends in the same scope
// Note: using C-style casting as we allow either pointers or integral types as IDs
// Note: the first variable argument must be a const format string
// Usage: AZ_PROFILE_INTERVAL_SCOPED(AZ::Debug::ProfileCategory, <unique interval id>, <printf style const format string>, format args...)
#define AZ_PROFILE_INTERVAL_SCOPED(category, id, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
AZ_INTERNAL_PROF_VERIFY_INTERVAL_ID(id); \
tmTimeSpan(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), (tm_uint64)(id), TM_MIN_TIME_SPAN_TRACK_ID + static_cast<AZ::Debug::ProfileCategoryPrimitiveType>(category), 0, TMZF_NONE, __VA_ARGS__)
// AZ_PROFILE_DATAPOINT (mapped to tmPlot APIs)
// Note: data points can have static or dynamic names, if using a dynamic name the first variable argument must be a const format string
// Usage: AZ_PROFILE_DATAPOINT(AZ::Debug::ProfileCategory, <printf style const format string>, format args...)
#define AZ_PROFILE_DATAPOINT(category, value, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmPlot(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), TM_PLOT_UNITS_REAL, TM_PLOT_DRAW_LINE, static_cast<double>(value), __VA_ARGS__)
#define AZ_PROFILE_DATAPOINT_PERCENT(category, value, ...) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmPlot(AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(category), TM_PLOT_UNITS_PERCENTAGE_DIRECT, TM_PLOT_DRAW_LINE, static_cast<double>(value), __VA_ARGS__)
// AZ_PROFILE_MEMORY_ALLOC
#define AZ_PROFILE_MEMORY_ALLOC(category, address, size, context) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmAlloc(AZ_INTERNAL_PROF_MEMORY_CAT_TO_FLAGS(category), address, size, context)
#define AZ_PROFILE_MEMORY_ALLOC_EX(category, filename, lineNumber, address, size, context) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmAllocEx(AZ_INTERNAL_PROF_MEMORY_CAT_TO_FLAGS(category), filename, lineNumber, address, size, context)
#define AZ_PROFILE_MEMORY_FREE(category, address) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmFree(AZ_INTERNAL_PROF_MEMORY_CAT_TO_FLAGS(category), address)
#define AZ_PROFILE_MEMORY_FREE_EX(category, filename, lineNumber, address) \
AZ_INTERNAL_PROF_VERIFY_CAT(category); \
tmFreeEx(AZ_INTERNAL_PROF_MEMORY_CAT_TO_FLAGS(category), filename, lineNumber, address)
#endif
@@ -1,49 +0,0 @@
/*
* 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
#ifdef AZ_PROFILE_TELEMETRY
#include <AzCore/base.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Debug/ProfilerBus.h>
#include <AzCore/EBus/EBus.h>
struct tm_api;
namespace RADTelemetry
{
class ProfileTelemetryRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual ~ProfileTelemetryRequests() = default;
virtual void ToggleEnabled() = 0;
virtual void SetAddress(const char* address, AZ::u16 port) = 0;
virtual void SetCaptureMask(AZ::Debug::ProfileCategoryPrimitiveType mask) = 0;
virtual void SetFrameAdvanceType(AZ::Debug::ProfileFrameAdvanceType type) = 0;
virtual AZ::Debug::ProfileCategoryPrimitiveType GetCaptureMask() = 0;
virtual AZ::Debug::ProfileCategoryPrimitiveType GetDefaultCaptureMask() = 0;
virtual tm_api* GetApiInstance() = 0;
};
using ProfileTelemetryRequestBus = AZ::EBus<ProfileTelemetryRequests>;
}
#endif
@@ -10,6 +10,7 @@
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/FileIOEventBus.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/PlatformIncl.h>
#include <AzCore/Utils/Utils.h>
@@ -208,7 +209,7 @@ namespace Platform
bool DeleteDir(const char* dirName)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "SystemFile::DeleteDir(util) - %s", dirName);
AZ_PROFILE_SCOPE(AzCore, "SystemFile::DeleteDir(util) - %s", dirName);
if (dirName)
{
@@ -11,7 +11,3 @@
# NOTE: functions in cmake are global, therefore adding functions to this file
# is being avoided to prevent overriding functions declared in other targets platfrom
# specific cmake files
if(LY_RAD_TELEMETRY_ENABLED)
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
endif()
@@ -169,7 +169,7 @@ namespace AZ::IO
void StorageDriveWin::PrepareRequest(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(request, "PrepareRequest was provided a null request.");
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
@@ -189,7 +189,7 @@ namespace AZ::IO
void StorageDriveWin::QueueRequest(FileRequest* request)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(request, "QueueRequest was provided a null request.");
AZStd::visit([this, request](auto&& args)
@@ -459,7 +459,7 @@ namespace AZ::IO
// Adding explicit scope here for profiling file Open & Close
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::ReadRequest OpenFile %s", m_name.c_str());
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::ReadRequest OpenFile %s", m_name.c_str());
TIMED_AVERAGE_WINDOW_SCOPE(m_fileOpenCloseTimeAverage);
// All reads are overlapped (asynchronous).
@@ -516,7 +516,7 @@ namespace AZ::IO
bool StorageDriveWin::ReadRequest(FileRequest* request)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::ReadRequest %s", m_name.c_str());
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::ReadRequest %s", m_name.c_str());
if (!m_cachesInitialized)
{
@@ -545,7 +545,7 @@ namespace AZ::IO
bool StorageDriveWin::ReadRequest(FileRequest* request, size_t readSlot)
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::ReadRequest %s", m_name.c_str());
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::ReadRequest %s", m_name.c_str());
if (!m_context->GetStreamerThreadSynchronizer().AreEventHandlesAvailable())
{
@@ -666,7 +666,7 @@ namespace AZ::IO
bool result = false;
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::ReadRequest ::ReadFile");
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::ReadRequest ::ReadFile");
result = ::ReadFile(file, output, readSize, nullptr, overlapped);
}
@@ -782,7 +782,7 @@ namespace AZ::IO
{
auto& fileExists = AZStd::get<FileRequest::FileExistsCheckData>(request->GetCommand());
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::FileExistsRequest %s : %s",
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::FileExistsRequest %s : %s",
m_name.c_str(), fileExists.m_path.GetRelativePath());
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileExistsTimeAverage);
@@ -838,7 +838,7 @@ namespace AZ::IO
{
auto& command = AZStd::get<FileRequest::FileMetaDataRetrievalData>(request->GetCommand());
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, "StorageDriveWin::FileMetaDataRetrievalRequest %s : %s",
AZ_PROFILE_SCOPE(AzCore, "StorageDriveWin::FileMetaDataRetrievalRequest %s : %s",
m_name.c_str(), command.m_path.GetRelativePath());
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileMetaDataRetrievalTimeAverage);
@@ -954,7 +954,7 @@ namespace AZ::IO
bool StorageDriveWin::FinalizeReads()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
bool hasWorked = false;
for (size_t readSlot = 0; readSlot < m_readSlots_active.size(); ++readSlot)
@@ -11,7 +11,3 @@
# NOTE: functions in cmake are global, therefore adding functions to this file
# is being avoided to prevent overriding functions declared in other targets platfrom
# specific cmake files
if(LY_RAD_TELEMETRY_ENABLED)
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
endif()
@@ -5,7 +5,3 @@
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
if(LY_RAD_TELEMETRY_ENABLED)
set(LY_COMPILE_DEFINITIONS PUBLIC AZ_PROFILE_TELEMETRY)
endif()
-148
View File
@@ -1191,154 +1191,6 @@ namespace UnitTest
//////////////////////////////////////////////////////////////////////////
}
class FrameProfilerComponentTest
: public AllocatorsFixture
, public FrameProfilerBus::Handler
{
public:
FrameProfilerComponentTest()
: AllocatorsFixture()
{
}
//////////////////////////////////////////////////////////////////////////
// FrameProfilerDrillerBus
void OnFrameProfilerData(const FrameProfiler::ThreadDataArray& data) override
{
for (size_t iThread = 0; iThread < data.size(); ++iThread)
{
const FrameProfiler::ThreadData& td = data[iThread];
FrameProfiler::ThreadData::RegistersMap::const_iterator regIt = td.m_registers.begin();
size_t numRegisters = m_numRegistersReceived;
for (; regIt != td.m_registers.end(); ++regIt)
{
const FrameProfiler::RegisterData& rd = regIt->second;
AZ_TEST_ASSERT(rd.m_function != NULL);
if (strstr(rd.m_function, "ChildFunction") || strstr(rd.m_function, "Profile1")) // filter only the test registers
{
++m_numRegistersReceived;
EXPECT_GT(rd.m_line, 0);
EXPECT_TRUE(rd.m_name == nullptr || strstr(rd.m_name, "Child1") || strstr(rd.m_name, "Custom name"));
AZ::u32 unitTestCrc = AZ_CRC("UnitTest", 0x8089cea8);
EXPECT_EQ(unitTestCrc, rd.m_systemId);
EXPECT_EQ(ProfilerRegister::PRT_TIME, rd.m_type);
EXPECT_FALSE(rd.m_frames.empty());
const FrameProfiler::FrameData& fd = rd.m_frames.back();
EXPECT_GT(fd.m_frameId, 0u);
EXPECT_GT(fd.m_timeData.m_time, 0);
EXPECT_GT(fd.m_timeData.m_calls, 0);
}
}
if (numRegisters < m_numRegistersReceived)
{
// we have received valid test registers for this thread, add it to the list
++m_numThreads;
}
}
}
//////////////////////////////////////////////////////////////////////////
int ChildFunction(int input)
{
AZ_PROFILE_TIMER("UnitTest", nullptr, NamedRegister);
int result = 5;
for (int i = 0; i < 10000; ++i)
{
result += i % (input + 3);
}
AZ_PROFILE_TIMER_END(NamedRegister);
return result;
}
int ChildFunction1(int input)
{
AZ_PROFILE_TIMER("UnitTest", "Child1");
int result = 5;
for (int i = 0; i < 10000; ++i)
{
result += i % (input + 1);
}
return result;
}
int Profile1(int numIterations)
{
AZ_PROFILE_TIMER("UnitTest", "Custom name");
int result = 0;
for (int i = 0; i < numIterations; ++i)
{
result += ChildFunction(i);
}
result += ChildFunction1(numIterations / 3);
return result;
}
void run()
{
FrameProfilerBus::Handler::BusConnect();
ComponentApplication app;
ComponentApplication::Descriptor desc;
desc.m_useExistingAllocator = true;
desc.m_enableDrilling = false; // we already created a memory driller for the test (AllocatorsFixture)
ComponentApplication::StartupParameters startupParams;
startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
Entity* systemEntity = app.Create(desc, startupParams);
systemEntity->CreateComponent<FrameProfilerComponent>();
systemEntity->Init();
systemEntity->Activate(); // start frame component
m_numThreads = 0;
m_numRegistersReceived = 0;
// tick to frame 1 and collect all the samples
app.Tick();
EXPECT_EQ(0, m_numThreads);
EXPECT_EQ(0, m_numRegistersReceived);
int numIterations = 10000;
{
AZStd::thread t1(AZStd::bind(&FrameProfilerComponentTest::Profile1, this, numIterations));
AZStd::thread t2(AZStd::bind(&FrameProfilerComponentTest::Profile1, this, numIterations));
AZStd::thread t3(AZStd::bind(&FrameProfilerComponentTest::Profile1, this, numIterations));
AZStd::thread t4(AZStd::bind(&FrameProfilerComponentTest::Profile1, this, numIterations));
t1.join();
t2.join();
t3.join();
t4.join();
}
// tick to frame 2 and collect all the samples
app.Tick();
EXPECT_EQ(4, m_numThreads);
EXPECT_EQ(m_numThreads * 3, m_numRegistersReceived);
FrameProfilerBus::Handler::BusDisconnect();
app.Destroy();
}
size_t m_numRegistersReceived;
size_t m_numThreads;
};
#if AZ_TRAIT_DISABLE_FAILED_FRAMEPROFILER_TEST
TEST_F(FrameProfilerComponentTest, DISABLED_Test)
#else
TEST_F(FrameProfilerComponentTest, Test)
#endif
{
run();
}
class SimpleEntityRefTestComponent
: public Component
{
@@ -507,6 +507,70 @@ namespace ConsoleSettingsRegistryTests
AZ::Interface<AZ::IConsole>::Unregister(&testConsole);
}
template<typename T>
using ConsoleDataWrapper = AZ::ConsoleDataWrapper<T, ConsoleThreadSafety<T>>;
TEST_P(ConsoleSettingsRegistryFixture, Console_RecordsUnregisteredCommands_And_IsAbleToDeferDispatchCommand_Successfully)
{
AZ::Console testConsole(*m_registry);
AZ::Interface<AZ::IConsole>::Register(&testConsole);
// GetDeferredHead is invoked for the side effect of to set the s_deferredHeadInvoked value to true
// This allows scoped console variables to be attached immediately
[[maybe_unused]] auto deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead();
ConsoleDataWrapper<int32_t> localTestInit{ {}, nullptr, "testInit", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<char> localTestChar{ {}, nullptr, "testChar", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<bool> localTestBool{ {}, nullptr, "testBool", "", AZ::ConsoleFunctorFlags::Null };
s_consoleFreeFunctionInvoked = false;
// Invoke the Commands for Scoped CVar variables above
auto configFileParams = GetParam();
auto testFilePath = m_testFolder / configFileParams.m_testConfigFileName;
EXPECT_TRUE(AZ::IO::SystemFile::Exists(testFilePath.c_str()));
testConsole.ExecuteConfigFile(testFilePath.Native());
EXPECT_EQ(3, localTestInit);
EXPECT_TRUE(static_cast<bool>(localTestBool));
EXPECT_EQ('Q', localTestChar);
// The following commands from the config files should have been deferred
ConsoleDataWrapper<int8_t> localTestInt8{ {}, nullptr, "testInt8", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<int16_t> localTestInt16{ {}, nullptr, "testInt16", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<int32_t> localTestInt32{ {}, nullptr, "testInt32", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<int64_t> localTestInt64{ {}, nullptr, "testInt64", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<uint8_t> localTestUInt8{ {}, nullptr, "testUInt8", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<uint16_t> localTestUInt16{ {}, nullptr, "testUInt16", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<uint32_t> localTestUInt32{ {}, nullptr, "testUInt32", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<uint64_t> localTestUInt64{ {}, nullptr, "testUInt64", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<float> localTestFloat{ {}, nullptr, "testFloat", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<double> localTestDouble{ {}, nullptr, "testDouble", "", AZ::ConsoleFunctorFlags::Null };
ConsoleDataWrapper<AZ::CVarFixedString> localTestString{ {}, nullptr, "testString", "", AZ::ConsoleFunctorFlags::Null };
// The scoped cvars just above should have all been deferred for execution
// Each of them should have executed resulting in the expected return value
EXPECT_TRUE(testConsole.ExecuteDeferredConsoleCommands());
EXPECT_EQ(24, localTestInt8);
EXPECT_EQ(-32, localTestInt16);
EXPECT_EQ(41, localTestInt32);
EXPECT_EQ(-51, localTestInt64);
EXPECT_EQ(3, localTestUInt8);
EXPECT_EQ(5, localTestUInt16);
EXPECT_EQ(6, localTestUInt32);
EXPECT_EQ(0xFFFF'FFFF'FFFF'FFFF, localTestUInt64);
EXPECT_FLOAT_EQ(1.0f, localTestFloat);
EXPECT_DOUBLE_EQ(2, localTestDouble);
EXPECT_STREQ("Stable", static_cast<AZ::CVarFixedString>(localTestString).c_str());
// All of the deferred console commands should have executed at this point
// Therefore this invocation should return false
EXPECT_FALSE(testConsole.ExecuteDeferredConsoleCommands());
AZ::Interface<AZ::IConsole>::Unregister(&testConsole);
}
static constexpr AZStd::string_view UserINIStyleContent =
R"(
-270
View File
@@ -171,276 +171,6 @@ namespace UnitTest
run();
}
class ProfilerTest
: public AllocatorsFixture
{
public:
int m_numRegistersReceived;
bool ReadRegisterCallback(const ProfilerRegister& reg, const AZStd::thread_id& id)
{
(void)reg;
(void)id;
switch (reg.m_type)
{
case ProfilerRegister::PRT_TIME:
{
AZ_TEST_ASSERT(reg.m_timeData.m_time > 0);
AZ_TEST_ASSERT(reg.m_timeData.m_calls > 0);
} break;
case ProfilerRegister::PRT_VALUE:
{
AZ_TEST_ASSERT(reg.m_userValues.m_value1 == 1 || reg.m_userValues.m_value1 == 2);
AZ_TEST_ASSERT(reg.m_userValues.m_value2 == 0 || reg.m_userValues.m_value2 == 2 || reg.m_userValues.m_value2 == 4);
AZ_TEST_ASSERT(reg.m_userValues.m_value3 == 0 || reg.m_userValues.m_value3 == 3 || reg.m_userValues.m_value3 == 6);
AZ_TEST_ASSERT(reg.m_userValues.m_value4 == 0 || reg.m_userValues.m_value4 == 4 || reg.m_userValues.m_value4 == 8);
AZ_TEST_ASSERT(reg.m_userValues.m_value5 == 0 || reg.m_userValues.m_value5 == 5 || reg.m_userValues.m_value5 == 10);
} break;
}
//AZ::u64 threadId = (AZ::u64)id.m_id;
//AZ_TracePrintf("Profiler","[%llu] '%s' '%s'(%d) %d Ms (Child calls: %d time: %d Ms) Parent: '%s'!\n",threadId,
// reg.m_name,reg.m_function,reg.m_line,reg.m_time.count(),reg.m_childrenCalls,reg.m_childrenTime.count(),reg.m_lastParent ? reg.m_lastParent->m_name : "No");
++m_numRegistersReceived;
return true;
}
int ChildFunction(int input)
{
AZ_PROFILE_TIMER("UnitTest");
auto start = AZStd::chrono::system_clock::now();
int result = 5;
for (int i = 0; i < 30000; ++i)
{
result += i % (input + 3);
}
auto end = AZStd::chrono::system_clock::now();
AZ_TEST_ASSERT(end >= start);
while (end <= start)
{
end = AZStd::chrono::system_clock::now();
}
return result;
}
int ChildFunction1(int input)
{
AZ_PROFILE_TIMER("UnitTest", "Child1");
auto start = AZStd::chrono::system_clock::now();
int result = 5;
for (int i = 0; i < 30000; ++i)
{
result += i % (input + 1);
}
auto end = AZStd::chrono::system_clock::now();
AZ_TEST_ASSERT(end >= start);
while (end <= start)
{
end = AZStd::chrono::system_clock::now();
}
return result;
}
int Profile1(int numIterations)
{
AZ_PROFILE_TIMER("UnitTest", "Custom name");
int result = 0;
for (int i = 0; i < numIterations; ++i)
{
result += ChildFunction(i);
}
result += ChildFunction1(numIterations / 3);
return result;
}
void UserValuesSet()
{
AZ_PROFILE_VALUE_SET("UnitTest", "UserValues1", 1);
AZ_PROFILE_VALUE_SET("UnitTest", "UserValues2", 1, 2);
AZ_PROFILE_VALUE_SET("UnitTest", "UserValues3", 1, 2, 3);
AZ::s64 v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5;
AZ_PROFILE_VALUE_SET("UnitTest", "UserValues4", v1, v2, v3, v4);
AZ_PROFILE_VALUE_SET("UnitTest", "UserValues5", v1, v2, v3, v4, v5);
// test named register
AZ_PROFILE_VALUE_SET_NAMED("UnitTest", "UserValues5", userValues5, v1, v2, v3, v4, v5);
#if defined(AZ_PROFILER_MACRO_DISABLE)
(void)v1;
(void)v2;
(void)v3;
(void)v4;
(void)v5;
#else
AZ_TEST_ASSERT(userValues5 != nullptr);
#endif // !defined(AZ_PROFILER_MACRO_DISABLE)
}
void UserValuesAdd(int numAdditions)
{
for (int i = 0; i < numAdditions; ++i)
{
AZ_PROFILE_VALUE_ADD("UnitTest", "UserValues1", 1);
AZ_PROFILE_VALUE_ADD("UnitTest", "UserValues2", 1, 2);
AZ_PROFILE_VALUE_ADD("UnitTest", "UserValues3", 1, 2, 3);
AZ::s64 v1 = 1, v2 = 2, v3 = 3, v4 = 4, v5 = 5;
AZ_PROFILE_VALUE_ADD("UnitTest", "UserValues4", v1, v2, v3, v4);
AZ_PROFILE_VALUE_ADD("UnitTest", "UserValues5", v1, v2, v3, v4, v5);
// test named register
AZ_PROFILE_VALUE_ADD_NAMED("UnitTest", "UserValues5", userValues5, v1, v2, v3, v4, v5);
#if defined(AZ_PROFILER_MACRO_DISABLE)
(void)v1;
(void)v2;
(void)v3;
(void)v4;
(void)v5;
#else
AZ_TEST_ASSERT(userValues5 != nullptr);
#endif // !defined(AZ_PROFILER_MACRO_DISABLE)
}
}
void run()
{
AZ_TEST_ASSERT(!Profiler::IsReady());
Profiler::Create();
AZ_TEST_ASSERT(Profiler::IsReady());
Profiler::Destroy();
AZ_TEST_ASSERT(!Profiler::IsReady());
#if !defined(AZ_PROFILER_MACRO_DISABLE)
Profiler::Create();
//Profile1();
//Profiler::Instance().ReadRegisterValues(AZStd::bind(&ProfilerTest::ReadRegisterCallback,this,AZStd::placeholders::_1,AZStd::placeholders::_2));
//Profiler::Instance().ResetRegisters();
AZStd::thread_id removeThreadId;
AZStd::chrono::microseconds elapsed[2];
int numIterations = 10000;
for (int i = 0; i < 2; ++i)
{
// for the second run we should not record any data
if (i == 1)
{
Profiler::Instance().DeactivateSystem("UnitTest");
}
AZStd::chrono::system_clock::time_point start = AZStd::chrono::system_clock::now();
AZStd::thread t1(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t2(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t3(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t4(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t5(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t6(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t7(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
AZStd::thread t8(AZStd::bind(&ProfilerTest::Profile1, this, numIterations));
removeThreadId = t4.get_id();
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
elapsed[i] = AZStd::chrono::system_clock::now() - start;
//AZ_Printf("Profiler","Elapsed time %d\n",elapsed[i].count());
if (i == 0)
{
// just as test remove all associated data and registers.
Profiler::Instance().RemoveThreadData(removeThreadId);
}
m_numRegistersReceived = 0;
Profiler::Instance().ReadRegisterValues(AZStd::bind(&ProfilerTest::ReadRegisterCallback, this, AZStd::placeholders::_1, AZStd::placeholders::_2));
if (i == 0)
{
AZ_TEST_ASSERT(m_numRegistersReceived == 7 * 3); // 3 registers for each thread (8 threads - 1 we removed the data for 't4')
}
else
{
AZ_TEST_ASSERT(m_numRegistersReceived == 0);
}
}
Profiler::Destroy();
// Test user value registers
Profiler::Create();
for (int i = 0; i < 2; ++i)
{
// for the second run we should not record any data
if (i == 1)
{
Profiler::Instance().DeactivateSystem("UnitTest");
}
AZStd::thread t1(AZStd::bind(&ProfilerTest::UserValuesSet, this));
AZStd::thread t2(AZStd::bind(&ProfilerTest::UserValuesSet, this));
AZStd::thread t3(AZStd::bind(&ProfilerTest::UserValuesSet, this));
AZStd::thread t4(AZStd::bind(&ProfilerTest::UserValuesSet, this));
AZStd::thread t5(AZStd::bind(&ProfilerTest::UserValuesAdd, this, 2));
AZStd::thread t6(AZStd::bind(&ProfilerTest::UserValuesAdd, this, 2));
AZStd::thread t7(AZStd::bind(&ProfilerTest::UserValuesAdd, this, 2));
AZStd::thread t8(AZStd::bind(&ProfilerTest::UserValuesAdd, this, 2));
removeThreadId = t4.get_id();
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
if (i == 0)
{
// just as test remove all associated data and registers.
Profiler::Instance().RemoveThreadData(removeThreadId);
}
m_numRegistersReceived = 0;
Profiler::Instance().ReadRegisterValues(AZStd::bind(&ProfilerTest::ReadRegisterCallback, this, AZStd::placeholders::_1, AZStd::placeholders::_2));
if (i == 0)
{
AZ_TEST_ASSERT(m_numRegistersReceived == 7 * 6); // 6 registers for each thread (8 threads - 1 we removed the data for 't4' )
}
else
{
AZ_TEST_ASSERT(m_numRegistersReceived == 0);
}
}
Profiler::Destroy();
#endif
}
};
#if AZ_TRAIT_DISABLE_FAILED_PROFILER_TEST
TEST_F(ProfilerTest, DISABLED_Test)
#else
TEST_F(ProfilerTest, Test)
#endif // AZ_TRAIT_DISABLE_FAILED_PROFILER_TEST
{
run();
}
TEST(Time, Test)
{
AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond();
@@ -6,16 +6,16 @@
*
*/
#include <AzCore/Math/Obb.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AZTestShared/Math/MathTestHelpers.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/Obb.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/Math/Vector3.h>
#include <AzCore/UnitTest/TestTypes.h>
using namespace AZ;
namespace UnitTest
namespace UnitTest::ObbTests
{
const Vector3 position(1.0f, 2.0f, 3.0f);
const Quaternion rotation = Quaternion::CreateRotationZ(Constants::QuarterPi);
@@ -151,4 +151,4 @@ namespace UnitTest
EXPECT_NEAR(obb.GetDistanceSq(Vector3(2.4f, 0.5f, 1.5f)), 0.5532f, 1e-3f);
EXPECT_NEAR(obb.GetDistanceSq(Vector3(1.1f, 7.3f, 5.8f)), 1.3612f, 1e-3f);
}
}
} // namespace UnitTest::ObbTests
@@ -83,7 +83,7 @@ namespace UnitTest
int ChildFunction0(int numIterations, int sleepTimeMilliseconds)
{
AZ_PROFILE_TIMER("UnitTest", CHILD_TIMER_STAT0);
AZ_PROFILE_SCOPE(UnitTest, CHILD_TIMER_STAT0);
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(sleepTimeMilliseconds));
int result = 5;
for (int i = 0; i < numIterations; ++i)
@@ -95,7 +95,7 @@ namespace UnitTest
int ChildFunction1(int numIterations, int sleepTimeMilliseconds)
{
AZ_PROFILE_TIMER("UnitTest", CHILD_TIMER_STAT1);
AZ_PROFILE_SCOPE(UnitTest, CHILD_TIMER_STAT1);
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(sleepTimeMilliseconds));
int result = 5;
for (int i = 0; i < numIterations; ++i)
@@ -107,7 +107,7 @@ namespace UnitTest
int ParentFunction(int numIterations, int sleepTimeMilliseconds)
{
AZ_PROFILE_TIMER("UnitTest", PARENT_TIMER_STAT);
AZ_PROFILE_SCOPE(UnitTest, PARENT_TIMER_STAT);
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(sleepTimeMilliseconds));
int result = 0;
result += ChildFunction0(numIterations, sleepTimeMilliseconds);
@@ -198,10 +198,11 @@ namespace UnitTest
AZStd::unique_ptr<Statistics::TimeDataStatisticsManager> m_statsManager;
};//class TimeDataStatisticsManagerTest
TEST_F(TimeDataStatisticsManagerTest, Test)
{
run();
}
// TODO:BUDGETS disabled until profiler budgets system comes online
// TEST_F(TimeDataStatisticsManagerTest, Test)
// {
// run();
// }
//End of all Tests of TimeDataStatisticsManagerTest
}//namespace UnitTest
@@ -60,7 +60,6 @@ set(FILES
SerializeContextFixture.h
Slice.cpp
State.cpp
StatisticalProfiler.cpp
Statistics.cpp
StreamerTests.cpp
StringFunc.cpp
@@ -11,6 +11,7 @@
#include <AzCore/Math/Crc.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/Component/NonUniformScaleBus.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/Slice/SliceSystemComponent.h>
#include <AzCore/Jobs/JobManagerComponent.h>
@@ -540,7 +541,7 @@ namespace AzFramework
const AZStd::function<void()>& workForNewThread,
const char* newThreadName)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZStd::thread_desc newThreadDesc;
newThreadDesc.m_cpuId = AFFINITY_MASK_USERTHREADS;
@@ -548,7 +549,7 @@ namespace AzFramework
AZStd::binary_semaphore binarySemaphore;
AZStd::thread newThread([&workForNewThread, &binarySemaphore, &newThreadName]
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzFramework,
AZ_PROFILE_SCOPE(AzFramework,
"Application::PumpSystemEventLoopWhileDoingWorkInNewThread:ThreadWorker %s", newThreadName);
workForNewThread();
@@ -559,7 +560,7 @@ namespace AzFramework
PumpSystemEventLoopUntilEmpty();
}
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(AZ::Debug::ProfileCategory::AzFramework,
AZ_PROFILE_SCOPE(AzFramework,
"Application::PumpSystemEventLoopWhileDoingWorkInNewThread:WaitOnThread %s", newThreadName);
newThread.join();
}
@@ -571,10 +572,14 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////////
void Application::RunMainLoop()
{
uint32_t frameCounter = 0;
while (!m_exitMainLoopRequested)
{
PumpSystemEventLoopUntilEmpty();
AZ_PROFILE_SCOPE(AzCore, "Frame %i", frameCounter);
Tick();
++frameCounter;
}
}
@@ -13,6 +13,7 @@
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/IO/FileIO.h>
@@ -206,7 +207,7 @@ namespace AZ::IO::ArchiveInternal
//////////////////////////////////////////////////////////////////////////
size_t ArchiveInternal::CZipPseudoFile::FRead(void* pDest, size_t nSize, size_t nCount, [[maybe_unused]] AZ::IO::HandleType fileHandle)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!GetFile())
{
@@ -271,7 +272,7 @@ namespace AZ::IO::ArchiveInternal
//////////////////////////////////////////////////////////////////////////
void* ArchiveInternal::CZipPseudoFile::GetFileData(size_t& nFileSize, [[maybe_unused]] AZ::IO::HandleType fileHandle)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
if (!GetFile())
{
@@ -685,7 +686,7 @@ namespace AZ::IO
//////////////////////////////////////////////////////////////////////////
AZ::IO::HandleType Archive::FOpen(AZStd::string_view pName, const char* szMode, uint32_t nInputFlags)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
const size_t pathLen = pName.size();
if (pathLen == 0 || pathLen >= MaxPath)
@@ -693,7 +694,7 @@ namespace AZ::IO
return AZ::IO::InvalidHandle;
}
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Game, "File: %.*s Archive: %p",
AZ_PROFILE_SCOPE(Game, "File: %.*s Archive: %p",
aznumeric_cast<int>(pName.size()), pName.data(), this);
SAutoCollectFileAccessTime accessTime(this);
@@ -716,7 +717,7 @@ namespace AZ::IO
}
const bool fileWritable = (nOSFlags & (AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeAppend | AZ::IO::OpenMode::ModeUpdate)) != AZ::IO::OpenMode::Invalid;
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Game, "File: %s Archive: %p", szFullPath->c_str(), this);
AZ_PROFILE_SCOPE(Game, "File: %s Archive: %p", szFullPath->c_str(), this);
if (fileWritable)
{
// we need to open the file for writing, but we failed to do so.
@@ -1094,8 +1095,8 @@ namespace AZ::IO
//////////////////////////////////////////////////////////////////////////
size_t Archive::FReadRaw(void* pData, size_t nSize, size_t nCount, AZ::IO::HandleType fileHandle)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Game, "Size: %d Archive: %p", nSize, this);
AZ_PROFILE_FUNCTION(AzCore);
AZ_PROFILE_SCOPE(Game, "Size: %d Archive: %p", nSize, this);
SAutoCollectFileAccessTime accessTime(this);
ArchiveInternal::CZipPseudoFile* pseudoFile = GetPseudoFile(fileHandle);
@@ -1112,7 +1113,7 @@ namespace AZ::IO
//////////////////////////////////////////////////////////////////////////
size_t Archive::FReadRawAll(void* pData, size_t nFileSize, AZ::IO::HandleType fileHandle)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
SAutoCollectFileAccessTime accessTime(this);
ArchiveInternal::CZipPseudoFile* pseudoFile = GetPseudoFile(fileHandle);
@@ -1130,7 +1131,7 @@ namespace AZ::IO
//////////////////////////////////////////////////////////////////////////
void* Archive::FGetCachedFileData(AZ::IO::HandleType fileHandle, size_t& nFileSize)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
SAutoCollectFileAccessTime accessTime(this);
ArchiveInternal::CZipPseudoFile* pseudoFile = GetPseudoFile(fileHandle);
@@ -167,7 +167,7 @@ namespace AzFramework
//=========================================================================
void EntityContext::HandleEntitiesAdded(const EntityList& entities)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
for (AZ::Entity* entity : entities)
{
@@ -184,7 +184,7 @@ namespace AzFramework
//=========================================================================
void EntityContext::HandleEntitiesRemoved(const EntityIdList& entityIds)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
for (AZ::EntityId id : entityIds)
{
@@ -155,7 +155,7 @@ namespace AzFramework
void SliceEntityOwnershipService::CreateRootSlice()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZ_Assert(m_rootAsset && m_rootAsset.Get(), "Root slice asset has not been created yet.");
@@ -164,7 +164,7 @@ namespace AzFramework
void SliceEntityOwnershipService::CreateRootSlice(AZ::SliceAsset* rootSliceAsset)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZ_Assert(m_rootAsset && m_rootAsset.Get(), "Root slice asset has not been created yet.");
AZ::Entity* rootEntity = new AZ::Entity();
@@ -240,7 +240,7 @@ namespace AzFramework
bool SliceEntityOwnershipService::LoadFromStream(AZ::IO::GenericStream& stream, bool remapIds, EntityIdToEntityIdMap* idRemapTable, const AZ::ObjectStream::FilterDescriptor& filterDesc)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZ_Assert(m_rootAsset, "The entity ownership service has not been initialized.");
@@ -259,7 +259,7 @@ namespace AzFramework
bool SliceEntityOwnershipService::HandleRootEntityReloadedFromStream(AZ::Entity* rootEntity, bool remapIds,
AZ::SliceComponent::EntityIdToEntityIdMap* idRemapTable)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
if (!rootEntity)
{
@@ -385,7 +385,7 @@ namespace AzFramework
void SliceEntityOwnershipService::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> readyAsset)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZ_ASSET_ATTACH_TO_SCOPE(readyAsset.Get());
AZ_Assert(readyAsset.GetAs<AZ::SliceAsset>(), "Asset is not a slice!");
@@ -472,7 +472,7 @@ namespace AzFramework
void SliceEntityOwnershipService::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
if (asset == m_rootAsset && asset.Get() != m_rootAsset.Get())
{
Reset();
@@ -548,7 +548,7 @@ namespace AzFramework
AZ::SliceComponent::SliceInstanceAddress SliceEntityOwnershipService::CloneSliceInstance(
AZ::SliceComponent::SliceInstanceAddress sourceInstance, AZ::SliceComponent::EntityIdToEntityIdMap& sourceToCloneEntityIdMap)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
AZ_Assert(sourceInstance.IsValid(), "Source slice instance is invalid.");
@@ -80,7 +80,7 @@ namespace AzFramework
{
using namespace AZ::IO;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(request, "PrepareRequest was provided a null request.");
if (AZStd::holds_alternative<FileRequest::ReadRequestData>(request->GetCommand()))
@@ -278,7 +278,7 @@ namespace AzFramework
{
using namespace AZ::IO;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
auto data = AZStd::get_if<FileRequest::ReadData>(&request->GetCommand());
AZ_Assert(data, "Request doing reading in the RemoteStorageDrive didn't contain read data.")
@@ -424,7 +424,7 @@ namespace AzFramework
{
using namespace AZ::IO;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore);
AZ_PROFILE_FUNCTION(AzCore);
TIMED_AVERAGE_WINDOW_SCOPE(m_getFileMetaDataTimeAverage);
AZ::u64 fileSize = 0;
@@ -619,7 +619,7 @@ namespace AzFramework
//=========================================================================
void ScriptComponent::LoadScript()
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Script, "Load: %s", m_script.GetHint().c_str());
AZ_PROFILE_SCOPE(Script, "Load: %s", m_script.GetHint().c_str());
// Load the script, find the base table, create the entity table
// find the Activate/Deactivate functions in the script and call them
@@ -634,7 +634,7 @@ namespace AzFramework
//=========================================================================
void ScriptComponent::UnloadScript()
{
AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Script, "Unload: %s", m_script.GetHint().c_str());
AZ_PROFILE_SCOPE(Script, "Unload: %s", m_script.GetHint().c_str());
DestroyEntityTable();
}
@@ -822,7 +822,7 @@ namespace AzFramework
lua_rawget(lua, baseStackIndex); // ScriptTable[OnActivate]
if (lua_isfunction(lua, -1))
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Script, "OnActivate");
AZ_PROFILE_SCOPE(Script, "OnActivate");
lua_rawgeti(lua, LUA_REGISTRYINDEX, m_table); // push the entity table as the only argument
AZ::Internal::LuaSafeCall(lua, 1, 0); // Call OnActivate
}
@@ -856,7 +856,7 @@ namespace AzFramework
lua_rawget(lua, -2); // ScriptTable[OnDeactivte]
if (lua_isfunction(lua, -1))
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::Script, "OnDeactivate");
AZ_PROFILE_SCOPE(Script, "OnDeactivate");
lua_pushvalue(lua, -3); // push the entity table as the only argument
AZ::Internal::LuaSafeCall(lua, 1, 0); // Call OnDeactivate
@@ -625,7 +625,7 @@ namespace AzFramework
return;
}
AZ_PROFILE_TIMER("TargetManager");
AZ_PROFILE_SCOPE(AzFramework, "TargetManager::SendTmMessage");
AZStd::vector<char, AZ::OSStdAllocator> msgBuffer;
AZ::IO::ByteContainerStream<AZStd::vector<char, AZ::OSStdAllocator> > outMsg(&msgBuffer);
@@ -651,7 +651,7 @@ namespace AzFramework
void TargetManagementComponent::DispatchMessages(MsgSlotId id)
{
AZ_PROFILE_TIMER("TargetManager");
AZ_PROFILE_SCOPE(AzFramework, "TargetManager::DispatchMessages");
AZStd::lock_guard<AZStd::mutex> lock(m_inboxMutex);
size_t maxMsgsToProcess = m_inbox.size();
TmMsgQueue::iterator itMsg = m_inbox.begin();
@@ -684,7 +684,7 @@ namespace AzFramework
{
if (m_networkImpl->m_gridMate)
{
AZ_PROFILE_TIMER("TargetManager");
AZ_PROFILE_SCOPE(AzFramework, "TargetManager::Tick");
if (!m_networkImpl->m_session && !m_networkImpl->m_gridSearch)
{
if (AZStd::chrono::system_clock::now() > m_reconnectionTime)
@@ -694,7 +694,7 @@ namespace AzFramework
}
{
AZ_PROFILE_TIMER("TargetManager", "Tick Gridmate");
AZ_PROFILE_SCOPE(AzFramework, "TargetManager::Tick Gridmate");
m_networkImpl->m_gridMate->Update();
if (m_networkImpl->m_session && m_networkImpl->m_session->GetReplicaMgr())
{
@@ -707,7 +707,7 @@ namespace AzFramework
if (m_networkImpl->m_session)
{
AZ_PROFILE_TIMER("TargetManager", "Send/Receive TmMsgs");
AZ_PROFILE_SCOPE(AzFramework, "TargetManager::Tick Send/Receive TmMsgs");
// Receive
for (unsigned int i = 0; i < m_networkImpl->m_session->GetNumberOfMembers(); ++i)
@@ -8,12 +8,12 @@
#include "CameraInput.h"
#include <AzCore/Console/IConsole.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/Math/Plane.h>
#include <AzCore/std/numeric.h>
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/Windowing/WindowBus.h>
namespace AzFramework
{
@@ -26,6 +26,13 @@ namespace AzFramework
"The default height of the ground plane to do intersection tests against when orbiting");
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
AZ_CVAR(
bool,
ed_cameraSystemUseCursor,
true,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"Should the camera use cursor absolute positions or motion deltas");
//! return -1.0f if inverted, 1.0f otherwise
constexpr static float Invert(const bool invert)
@@ -134,9 +141,13 @@ namespace AzFramework
bool CameraSystem::HandleEvents(const InputEvent& event)
{
if (const auto& horizonalMotion = AZStd::get_if<HorizontalMotionEvent>(&event))
if (const auto& cursor = AZStd::get_if<CursorEvent>(&event))
{
m_motionDelta.m_x = horizonalMotion->m_delta;
m_cursorState.SetCurrentPosition(cursor->m_position);
}
else if (const auto& horizontalMotion = AZStd::get_if<HorizontalMotionEvent>(&event))
{
m_motionDelta.m_x = horizontalMotion->m_delta;
}
else if (const auto& verticalMotion = AZStd::get_if<VerticalMotionEvent>(&event))
{
@@ -147,15 +158,18 @@ namespace AzFramework
m_scrollDelta = scroll->m_delta;
}
m_handlingEvents = m_cameras.HandleEvents(event, m_motionDelta, m_scrollDelta);
m_handlingEvents =
m_cameras.HandleEvents(event, ed_cameraSystemUseCursor ? m_cursorState.CursorDelta() : m_motionDelta, m_scrollDelta);
return m_handlingEvents;
}
Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime)
{
const auto nextCamera = m_cameras.StepCamera(targetCamera, m_motionDelta, m_scrollDelta, deltaTime);
const auto nextCamera = m_cameras.StepCamera(
targetCamera, ed_cameraSystemUseCursor ? m_cursorState.CursorDelta() : m_motionDelta, m_scrollDelta, deltaTime);
m_cursorState.Update();
m_motionDelta = ScreenVector{ 0, 0 };
m_scrollDelta = 0.0f;
@@ -727,18 +741,36 @@ namespace AzFramework
Camera camera;
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
// article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
const float lookRate = AZStd::exp2(cameraProps.m_rotateSmoothnessFn());
const float lookT = AZStd::exp2(-lookRate * deltaTime);
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT);
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT);
const float moveRate = AZStd::exp2(cameraProps.m_translateSmoothnessFn());
const float moveT = AZStd::exp2(-moveRate * deltaTime);
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT);
if (cameraProps.m_rotateSmoothingEnabledFn())
{
const float lookRate = AZStd::exp2(cameraProps.m_rotateSmoothnessFn());
const float lookTime = AZStd::exp2(-lookRate * deltaTime);
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookTime);
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookTime);
}
else
{
camera.m_pitch = targetCamera.m_pitch;
camera.m_yaw = targetYaw;
}
if (cameraProps.m_translateSmoothingEnabledFn())
{
const float moveRate = AZStd::exp2(cameraProps.m_translateSmoothnessFn());
const float moveTime = AZStd::exp2(-moveRate * deltaTime);
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveTime);
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveTime);
}
else
{
camera.m_lookDist = targetCamera.m_lookDist;
camera.m_lookAt = targetCamera.m_lookAt;
}
return camera;
}
InputEvent BuildInputEvent(const InputChannel& inputChannel)
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize)
{
const auto& inputChannelId = inputChannel.GetInputChannelId();
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
@@ -753,7 +785,16 @@ namespace AzFramework
// accept active mouse channel updates, inactive movement channels will just have a 0 delta
if (inputChannel.IsActive())
{
if (inputChannelId == InputDeviceMouse::Movement::X)
if (inputChannelId == InputDeviceMouse::SystemCursorPosition)
{
const auto* position = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
AZ_Assert(position, "Expected PositionData2D but found nullptr");
return CursorEvent{ ScreenPoint(
position->m_normalizedPosition.GetX() * windowSize.m_width,
position->m_normalizedPosition.GetY() * windowSize.m_height) };
}
else if (inputChannelId == InputDeviceMouse::Movement::X)
{
return HorizontalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
}
@@ -761,6 +802,7 @@ namespace AzFramework
{
return VerticalMotionEvent{ aznumeric_cast<int>(inputChannel.GetValue()) };
}
else if (inputChannelId == InputDeviceMouse::Movement::Z)
{
return ScrollEvent{ inputChannel.GetValue() };
@@ -8,17 +8,23 @@
#pragma once
#include <AzCore/Console/IConsole.h>
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/std/containers/variant.h>
#include <AzCore/std/optional.h>
#include <AzFramework/Input/Channels/InputChannel.h>
#include <AzFramework/Viewport/ClickDetector.h>
#include <AzFramework/Viewport/CursorState.h>
#include <AzFramework/Viewport/ScreenGeometry.h>
#include <AzFramework/Viewport/ViewportId.h>
namespace AzFramework
{
AZ_CVAR_EXTERNED(bool, ed_cameraSystemUseCursor);
struct WindowSize;
//! Returns Euler angles (pitch, roll, yaw) for the incoming orientation.
//! @note Order of rotation is Z, Y, X.
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
@@ -79,6 +85,11 @@ namespace AzFramework
using HorizontalMotionEvent = MotionEvent<struct HorizontalMotionTag>;
using VerticalMotionEvent = MotionEvent<struct VerticalMotionTag>;
struct CursorEvent
{
ScreenPoint m_position;
};
struct ScrollEvent
{
float m_delta;
@@ -93,7 +104,8 @@ namespace AzFramework
};
//! Represents a type-safe union of input events that are handled by the camera system.
using InputEvent = AZStd::variant<AZStd::monostate, HorizontalMotionEvent, VerticalMotionEvent, ScrollEvent, DiscreteInputEvent>;
using InputEvent =
AZStd::variant<AZStd::monostate, HorizontalMotionEvent, VerticalMotionEvent, CursorEvent, ScrollEvent, DiscreteInputEvent>;
//! Base class for all camera behaviors.
//! The core interface consists of:
@@ -219,10 +231,14 @@ namespace AzFramework
//! Properties to use to configure behavior across all types of camera.
struct CameraProps
{
AZStd::function<float()>
m_rotateSmoothnessFn; //!< Rotate smoothing value (useful approx range 3-6, higher values give sharper feel).
AZStd::function<float()>
m_translateSmoothnessFn; //!< Translate smoothing value (useful approx range 3-6, higher values give sharper feel).
//! Rotate smoothing value (useful approx range 3-6, higher values give sharper feel).
AZStd::function<float()> m_rotateSmoothnessFn;
//! Translate smoothing value (useful approx range 3-6, higher values give sharper feel).
AZStd::function<float()> m_translateSmoothnessFn;
//! Enable/disable rotation smoothing.
AZStd::function<bool()> m_rotateSmoothingEnabledFn;
//! Enable/disable translation smoothing.
AZStd::function<bool()> m_translateSmoothingEnabledFn;
};
//! An interpolation function to smoothly interpolate all camera properties from currentCamera to targetCamera.
@@ -262,12 +278,16 @@ namespace AzFramework
public:
bool HandleEvents(const InputEvent& event);
Camera StepCamera(const Camera& targetCamera, float deltaTime);
bool HandlingEvents() const { return m_handlingEvents; }
bool HandlingEvents() const
{
return m_handlingEvents;
}
Cameras m_cameras; //!< Represents a collection of camera inputs that together provide a camera controller.
private:
ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional.
CursorState m_cursorState; //!< The current and previous position of the cursor (used to calculate movement delta).
float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional.
bool m_handlingEvents = false; //!< Is the camera system currently handling events (events are consumed and not propagated).
};
@@ -548,5 +568,5 @@ namespace AzFramework
}
//! Map from a generic InputChannel event to a camera specific InputEvent.
InputEvent BuildInputEvent(const InputChannel& inputChannel);
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize);
} // namespace AzFramework
@@ -8,6 +8,7 @@
#include "EntityVisibilityBoundsUnionSystem.h"
#include <AzCore/Debug/Profiler.h>
#include <AzFramework/Visibility/BoundsBus.h>
#include <cstring>
@@ -42,7 +43,7 @@ namespace AzFramework
void EntityVisibilityBoundsUnionSystem::OnEntityActivated(AZ::Entity* entity)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
// ignore any entity that might activate which does not have a TransformComponent
if (entity->GetTransform() == nullptr)
@@ -68,7 +69,7 @@ namespace AzFramework
void EntityVisibilityBoundsUnionSystem::OnEntityDeactivated(AZ::Entity* entity)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
// ignore any entity that might deactivate which does not have a TransformComponent
if (entity->GetTransform() == nullptr)
@@ -89,7 +90,7 @@ namespace AzFramework
void EntityVisibilityBoundsUnionSystem::UpdateVisibilitySystem(AZ::Entity* entity, EntityVisibilityBoundsUnionInstance& instance)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
if (const auto& localEntityBoundsUnions = instance.m_localEntityBoundsUnion; localEntityBoundsUnions.IsValid())
{
@@ -136,7 +137,7 @@ namespace AzFramework
void EntityVisibilityBoundsUnionSystem::ProcessEntityBoundsUnionRequests()
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
// iterate over all entities whose bounds changed and recalculate them
for (const auto& entity : m_entityBoundsDirty)
@@ -155,7 +156,7 @@ namespace AzFramework
void EntityVisibilityBoundsUnionSystem::OnTransformUpdated(AZ::Entity* entity)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
// update the world transform of the visibility bounds union
if (auto instance_it = m_entityVisibilityBoundsUnionInstanceMapping.find(entity);
@@ -34,7 +34,7 @@ namespace AzFramework
{
void EntityVisibilityQuery::UpdateVisibility(const AzFramework::CameraState& cameraState)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzFramework);
AZ_PROFILE_FUNCTION(AzFramework);
auto* visSystem = AZ::Interface<AzFramework::IVisibilitySystem>::Get();
if (!visSystem)
+3 -9
View File
@@ -10,7 +10,6 @@
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common)
set(LY_STATISTICAL_PROFILING_ENABLED OFF CACHE BOOL "Enables statistical profiling when using AZ_PROFILE_SCOPE. If True, it takes effect only if RAD Telemetry is disabled.")
set(LY_TOUCHBENDING_LAYER_BIT 63 CACHE STRING "Use TouchBending as the collision layer. The TouchBending layer can be a number from 1 to 63 (Default=63).")
ly_add_target(
@@ -38,14 +37,6 @@ ly_add_target(
3rdParty::lz4
)
if(LY_STATISTICAL_PROFILING_ENABLED)
ly_add_source_properties(
SOURCES AzFramework/Debug/StatisticalProfilerProxy.h
PROPERTY COMPILE_DEFINITIONS
VALUES AZ_STATISTICAL_PROFILING_ENABLED
)
endif()
ly_add_source_properties(
SOURCES
AzFramework/Physics/Collision/CollisionGroups.cpp
@@ -70,6 +61,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
PRIVATE
AZ::AzCore
AZ::AzFramework
PUBLIC
AZ::AzTest
AZ::AzTestShared
)
if(PAL_TRAIT_BUILD_HOST_TOOLS)
@@ -59,10 +59,15 @@ namespace UnitTest
m_cameraSystem->m_cameras.AddCamera(m_firstPersonRotateCamera);
m_cameraSystem->m_cameras.AddCamera(m_firstPersonTranslateCamera);
m_cameraSystem->m_cameras.AddCamera(orbitCamera);
// these tests rely on using motion delta, not cursor positions (default is true)
AzFramework::ed_cameraSystemUseCursor = false;
}
void TearDown() override
{
AzFramework::ed_cameraSystemUseCursor = true;
m_firstPersonRotateCamera.reset();
m_firstPersonTranslateCamera.reset();
@@ -0,0 +1,41 @@
/*
* 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 <AzFramework/Windowing/WindowBus.h>
#include <gmock/gmock.h>
namespace UnitTest
{
class MockWindowRequests : public AzFramework::WindowRequestBus::Handler
{
public:
void Connect(AzFramework::NativeWindowHandle handle)
{
AzFramework::WindowRequestBus::Handler::BusConnect(handle);
}
void Disconnect()
{
AzFramework::WindowRequestBus::Handler::BusDisconnect();
}
// AzFramework::WindowRequestBus overrides ...
MOCK_METHOD1(SetWindowTitle, void(const AZStd::string&));
MOCK_CONST_METHOD0(GetClientAreaSize, AzFramework::WindowSize());
MOCK_METHOD1(ResizeClientArea, void(AzFramework::WindowSize clientAreaSize));
MOCK_CONST_METHOD0(GetFullScreenState, bool());
MOCK_METHOD1(SetFullScreenState, void(bool));
MOCK_CONST_METHOD0(CanToggleFullScreenState, bool());
MOCK_METHOD0(ToggleFullScreenState, void());
MOCK_CONST_METHOD0(GetDpiScaleFactor, float());
MOCK_CONST_METHOD0(GetSyncInterval, uint32_t());
MOCK_CONST_METHOD0(GetDisplayRefreshRate, uint32_t());
};
} // namespace UnitTest
@@ -8,6 +8,7 @@
set(FILES
Mocks/MockSpawnableEntitiesInterface.h
Mocks/MockWindowRequests.h
Utils/Utils.h
Utils/Utils.cpp
FrameworkApplicationFixture.h

Some files were not shown because too many files have changed in this diff Show More