From 693882146771eb4eb853ddece35c8dd01a39414e Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 7 Jul 2021 15:15:33 +0200 Subject: [PATCH] Add even more profiler events --- .../Editor/Managed/ManagedEditor.Internal.cpp | 13 +++++++-- Source/Editor/Modules/SceneModule.cs | 2 ++ Source/Editor/States/PlayingState.cs | 8 ++++++ Source/Editor/Utilities/DuplicateScenes.cs | 27 +++++++++++++++++++ Source/Engine/Content/JsonAsset.cpp | 7 ++++- .../Content/Storage/JsonStorageProxy.cpp | 13 +++++++-- Source/Engine/Core/Config/GameSettings.cpp | 6 ++++- Source/Engine/Level/Actor.cpp | 15 ++++++++--- Source/Engine/Level/Level.cpp | 13 ++++++--- Source/Engine/Level/Prefabs/Prefab.Apply.cpp | 15 ++++++++--- Source/Engine/Level/Prefabs/PrefabManager.cpp | 5 +++- .../Engine/Scripting/Plugins/PluginManager.cs | 4 +++ Source/Engine/Scripting/Scripting.cpp | 5 +++- 13 files changed, 115 insertions(+), 18 deletions(-) diff --git a/Source/Editor/Managed/ManagedEditor.Internal.cpp b/Source/Editor/Managed/ManagedEditor.Internal.cpp index 4e3f5f1f1..4f0370b44 100644 --- a/Source/Editor/Managed/ManagedEditor.Internal.cpp +++ b/Source/Editor/Managed/ManagedEditor.Internal.cpp @@ -37,6 +37,7 @@ #include "Engine/Utilities/Encryption.h" #include "Engine/Navigation/Navigation.h" #include "Engine/Particles/ParticleEmitter.h" +#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Input/Input.h" #include "Engine/Input/Mouse.h" #include "Engine/Input/Keyboard.h" @@ -1007,11 +1008,16 @@ public: static void DeserializeSceneObject(SceneObject* sceneObject, MonoString* jsonObj) { + PROFILE_CPU_NAMED("DeserializeSceneObject"); + StringAnsi json; MUtils::ToString(jsonObj, json); rapidjson_flax::Document document; - document.Parse(json.Get(), json.Length()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(json.Get(), json.Length()); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); @@ -1022,7 +1028,10 @@ public: modifier->EngineBuild = FLAXENGINE_VERSION_BUILD; Scripting::ObjectsLookupIdMapping.Set(&modifier.Value->IdsMapping); - sceneObject->Deserialize(document, modifier.Value); + { + PROFILE_CPU_NAMED("Deserialize"); + sceneObject->Deserialize(document, modifier.Value); + } } static void LoadAsset(Guid* id) diff --git a/Source/Editor/Modules/SceneModule.cs b/Source/Editor/Modules/SceneModule.cs index 0b4206526..33d41ddd6 100644 --- a/Source/Editor/Modules/SceneModule.cs +++ b/Source/Editor/Modules/SceneModule.cs @@ -371,12 +371,14 @@ namespace FlaxEditor.Modules /// True if cleanup all data (including serialized and cached data). Otherwise will just clear living references to the scene objects. public void ClearRefsToSceneObjects(bool fullCleanup = false) { + Profiler.BeginEvent("SceneModule.ClearRefsToSceneObjects"); Editor.SceneEditing.Deselect(); if (fullCleanup) { Undo.Clear(); } + Profiler.EndEvent(); } private void OnSceneLoaded(Scene scene, Guid sceneId) diff --git a/Source/Editor/States/PlayingState.cs b/Source/Editor/States/PlayingState.cs index 6b946b23e..171022745 100644 --- a/Source/Editor/States/PlayingState.cs +++ b/Source/Editor/States/PlayingState.cs @@ -87,15 +87,18 @@ namespace FlaxEditor.States private void CacheSelection() { + Profiler.BeginEvent("PlayingState.CacheSelection"); _selectedObjects.Clear(); for (int i = 0; i < Editor.SceneEditing.Selection.Count; i++) { _selectedObjects.Add(Editor.SceneEditing.Selection[i].ID); } + Profiler.EndEvent(); } private void RestoreSelection() { + Profiler.BeginEvent("PlayingState.RestoreSelection"); var count = Editor.SceneEditing.Selection.Count; Editor.SceneEditing.Selection.Clear(); for (int i = 0; i < _selectedObjects.Count; i++) @@ -106,6 +109,7 @@ namespace FlaxEditor.States } if (Editor.SceneEditing.Selection.Count != count) Editor.SceneEditing.OnSelectionChanged(); + Profiler.EndEvent(); } /// @@ -114,6 +118,7 @@ namespace FlaxEditor.States /// public override void OnEnter() { + Profiler.BeginEvent("PlayingState.OnEnter"); Editor.OnPlayBeginning(); CacheSelection(); @@ -137,6 +142,7 @@ namespace FlaxEditor.States RestoreSelection(); Editor.OnPlayBegin(); + Profiler.EndEvent(); } private void SetupEditorEnvOptions() @@ -156,6 +162,7 @@ namespace FlaxEditor.States /// public override void OnExit(State nextState) { + Profiler.BeginEvent("PlayingState.OnExit"); IsPaused = true; // Remove references to the scene objects @@ -178,6 +185,7 @@ namespace FlaxEditor.States RestoreSelection(); Editor.OnPlayEnd(); + Profiler.EndEvent(); } } } diff --git a/Source/Editor/Utilities/DuplicateScenes.cs b/Source/Editor/Utilities/DuplicateScenes.cs index bff0b6714..aaed7fff7 100644 --- a/Source/Editor/Utilities/DuplicateScenes.cs +++ b/Source/Editor/Utilities/DuplicateScenes.cs @@ -37,6 +37,7 @@ namespace FlaxEditor.Utilities { if (HasData) throw new InvalidOperationException("DuplicateScenes has already gathered scene data."); + Profiler.BeginEvent("DuplicateScenes.GatherSceneData"); Editor.Log("Collecting scene data"); @@ -44,7 +45,10 @@ namespace FlaxEditor.Utilities var scenes = Level.Scenes; int scenesCount = scenes.Length; if (scenesCount == 0) + { + Profiler.EndEvent(); throw new InvalidOperationException("Cannot gather scene data. No scene loaded."); + } var sceneIds = new Guid[scenesCount]; for (int i = 0; i < scenesCount; i++) { @@ -66,17 +70,24 @@ namespace FlaxEditor.Utilities // Delete old scenes if (Level.UnloadAllScenes()) + { + Profiler.EndEvent(); throw new FlaxException("Failed to unload scenes."); + } FlaxEngine.Scripting.FlushRemovedObjects(); // Ensure that old scenes has been unregistered { var noScenes = Level.Scenes; if (noScenes != null && noScenes.Length != 0) + { + Profiler.EndEvent(); throw new FlaxException("Failed to unload scenes."); + } } Editor.Log(string.Format("Gathered {0} scene(s)!", scenesCount)); + Profiler.EndEvent(); } /// @@ -86,6 +97,7 @@ namespace FlaxEditor.Utilities { if (!HasData) throw new InvalidOperationException("DuplicateScenes has not gathered scene data yet."); + Profiler.BeginEvent("DuplicateScenes.CreateScenes"); Editor.Log("Creating scenes"); @@ -96,8 +108,13 @@ namespace FlaxEditor.Utilities var data = _scenesData[i]; var scene = Level.LoadSceneFromBytes(data.Bytes); if (scene == null) + { + Profiler.EndEvent(); throw new FlaxException("Failed to deserialize scene"); + } } + + Profiler.EndEvent(); } /// @@ -105,14 +122,19 @@ namespace FlaxEditor.Utilities /// public void DeletedScenes() { + Profiler.BeginEvent("DuplicateScenes.DeletedScenes"); Editor.Log("Restoring scene data"); // TODO: here we can keep changes for actors marked to keep their state after simulation // Delete new scenes if (Level.UnloadAllScenes()) + { + Profiler.EndEvent(); throw new FlaxException("Failed to unload scenes."); + } FlaxEngine.Scripting.FlushRemovedObjects(); + Profiler.EndEvent(); } /// @@ -122,6 +144,7 @@ namespace FlaxEditor.Utilities { if (!HasData) throw new InvalidOperationException("DuplicateScenes has not gathered scene data yet."); + Profiler.BeginEvent("DuplicateScenes.RestoreSceneData"); // Deserialize old scenes for (int i = 0; i < _scenesData.Count; i++) @@ -129,7 +152,10 @@ namespace FlaxEditor.Utilities var data = _scenesData[i]; var scene = Level.LoadSceneFromBytes(data.Bytes); if (scene == null) + { + Profiler.EndEvent(); throw new FlaxException("Failed to deserialize scene"); + } // Restore `dirty` state if (data.IsDirty) @@ -138,6 +164,7 @@ namespace FlaxEditor.Utilities _scenesData.Clear(); Editor.Log("Restored previous scenes"); + Profiler.EndEvent(); } } } diff --git a/Source/Engine/Content/JsonAsset.cpp b/Source/Engine/Content/JsonAsset.cpp index c9a07e665..5015d61d9 100644 --- a/Source/Engine/Content/JsonAsset.cpp +++ b/Source/Engine/Content/JsonAsset.cpp @@ -16,6 +16,7 @@ #include "Engine/Content/Factories/JsonAssetFactory.h" #include "Engine/Core/Cache.h" #include "Engine/Debug/Exceptions/JsonParseException.h" +#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Utilities/StringConverter.h" @@ -31,6 +32,7 @@ String JsonAssetBase::GetData() const { if (Data == nullptr) return String::Empty; + PROFILE_CPU_NAMED("JsonAsset.GetData"); // Get serialized data rapidjson_flax::StringBuffer buffer; @@ -133,7 +135,10 @@ Asset::LoadResult JsonAssetBase::loadAsset() #endif // Parse json document - Document.Parse(data.Get(), data.Length()); + { + PROFILE_CPU_NAMED("Json.Parse"); + Document.Parse(data.Get(), data.Length()); + } if (Document.HasParseError()) { Log::JsonParseException(Document.GetParseError(), Document.GetErrorOffset()); diff --git a/Source/Engine/Content/Storage/JsonStorageProxy.cpp b/Source/Engine/Content/Storage/JsonStorageProxy.cpp index 1d5dbdf19..5982691e7 100644 --- a/Source/Engine/Content/Storage/JsonStorageProxy.cpp +++ b/Source/Engine/Content/Storage/JsonStorageProxy.cpp @@ -8,6 +8,7 @@ #include "Engine/Serialization/JsonWriters.h" #include "Engine/Level/Types.h" #include "Engine/Debug/Exceptions/JsonParseException.h" +#include "Engine/Profiler/ProfilerCPU.h" #include bool JsonStorageProxy::IsValidExtension(const StringView& extension) @@ -17,6 +18,7 @@ bool JsonStorageProxy::IsValidExtension(const StringView& extension) bool JsonStorageProxy::GetAssetInfo(const StringView& path, Guid& resultId, String& resultDataTypeName) { + PROFILE_CPU(); // TODO: we could just open file and start reading until we find 'ID:..' without parsing whole file - could be much more faster // Load file @@ -28,7 +30,10 @@ bool JsonStorageProxy::GetAssetInfo(const StringView& path, Guid& resultId, Stri // Parse data rapidjson_flax::Document document; - document.Parse((const char*)fileData.Get(), fileData.Count()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse((const char*)fileData.Get(), fileData.Count()); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset(), path); @@ -81,6 +86,7 @@ void ChangeIds(rapidjson_flax::Value& obj, rapidjson_flax::Document& document, c bool JsonStorageProxy::ChangeId(const StringView& path, const Guid& newId) { #if USE_EDITOR + PROFILE_CPU(); // Load file Array fileData; @@ -91,7 +97,10 @@ bool JsonStorageProxy::ChangeId(const StringView& path, const Guid& newId) // Parse data rapidjson_flax::Document document; - document.Parse((const char*)fileData.Get(), fileData.Count()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse((const char*)fileData.Get(), fileData.Count()); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset(), path); diff --git a/Source/Engine/Core/Config/GameSettings.cpp b/Source/Engine/Core/Config/GameSettings.cpp index 26d9175b0..1ccdf1e51 100644 --- a/Source/Engine/Core/Config/GameSettings.cpp +++ b/Source/Engine/Core/Config/GameSettings.cpp @@ -19,6 +19,7 @@ #include "Engine/Content/AssetReference.h" #include "Engine/Engine/EngineService.h" #include "Engine/Engine/Globals.h" +#include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Streaming/StreamingSettings.h" class GameSettingsService : public EngineService @@ -74,6 +75,7 @@ GameSettings* GameSettings::Get() { // Load root game settings asset. // It may be missing in editor during dev but must be ready in the build game. + PROFILE_CPU(); const auto assetPath = Globals::ProjectContentFolder / TEXT("GameSettings.json"); GameSettingsAsset = Content::LoadAsync(assetPath); if (GameSettingsAsset == nullptr) @@ -99,6 +101,8 @@ GameSettings* GameSettings::Get() bool GameSettings::Load() { + PROFILE_CPU(); + // Load main settings asset auto settings = Get(); if (!settings) @@ -143,7 +147,7 @@ bool GameSettings::Load() void GameSettings::Apply() { - // TODO: impl this + PROFILE_CPU(); #define APPLY_SETTINGS(type) \ { \ type* obj = type::Get(); \ diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp index 20ec4cb7a..2e3f75525 100644 --- a/Source/Engine/Level/Actor.cpp +++ b/Source/Engine/Level/Actor.cpp @@ -1599,7 +1599,10 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM // Load JSON rapidjson_flax::Document document; - document.Parse(buffer, bufferSize); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(buffer, bufferSize); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); @@ -1638,7 +1641,10 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM // Load JSON rapidjson_flax::Document document; - document.Parse(buffer, bufferSize); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(buffer, bufferSize); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); @@ -1763,7 +1769,10 @@ void Actor::FromJson(const StringAnsiView& json) // Load JSON rapidjson_flax::Document document; - document.Parse(json.Get(), json.Length()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(json.Get(), json.Length()); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp index 916153a8b..5b99ba5ff 100644 --- a/Source/Engine/Level/Level.cpp +++ b/Source/Engine/Level/Level.cpp @@ -496,6 +496,7 @@ public: // - load scenes (from temporary files) // Note: we don't want to override original scene files + PROFILE_CPU_NAMED("Level.ReloadScripts"); LOG(Info, "Scripts reloading start"); const auto startTime = DateTime::NowUTC(); @@ -565,7 +566,10 @@ public: // Parse json const auto& sceneData = scenes[i].Data; ISerializable::SerializeDocument document; - document.Parse(sceneData.GetString(), sceneData.GetSize()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(sceneData.GetString(), sceneData.GetSize()); + } if (document.HasParseError()) { LOG(Error, "Failed to deserialize scene {0}. Result: {1}", scenes[i].Name, GetParseError_En(document.GetParseError())); @@ -851,7 +855,10 @@ bool Level::loadScene(const BytesContainer& sceneData, bool autoInitialize, Scen // Parse scene JSON file rapidjson_flax::Document document; - document.Parse(sceneData.Get(), sceneData.Length()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse(sceneData.Get(), sceneData.Length()); + } if (document.HasParseError()) { Log::JsonParseException(document.GetParseError(), document.GetErrorOffset()); @@ -869,9 +876,7 @@ bool Level::loadScene(rapidjson_flax::Document& document, bool autoInitialize, S LOG(Error, "Missing Data member."); return true; } - const int32 saveEngineBuild = JsonTools::GetInt(document, "EngineBuild", 0); - return loadScene(data->value, saveEngineBuild, autoInitialize, outScene); } diff --git a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp index abad0c275..48ecc7e7c 100644 --- a/Source/Engine/Level/Prefabs/Prefab.Apply.cpp +++ b/Source/Engine/Level/Prefabs/Prefab.Apply.cpp @@ -217,7 +217,10 @@ void PrefabInstanceData::SerializePrefabInstances(Array& pre writer.EndArray(); // Parse json to get DOM - instance.Data.Parse(tmpBuffer.GetString(), tmpBuffer.GetSize()); + { + PROFILE_CPU_NAMED("Json.Parse"); + instance.Data.Parse(tmpBuffer.GetString(), tmpBuffer.GetSize()); + } if (instance.Data.HasParseError()) { LOG(Warning, "Failed to parse serialized scene objects data."); @@ -462,7 +465,10 @@ bool PrefabInstanceData::SynchronizePrefabInstances(Array& p writer.EndArray(); // Parse json to get DOM - defaultInstanceData.Parse(tmpBuffer.GetString(), tmpBuffer.GetSize()); + { + PROFILE_CPU_NAMED("Json.Parse"); + defaultInstanceData.Parse(tmpBuffer.GetString(), tmpBuffer.GetSize()); + } if (defaultInstanceData.HasParseError()) { LOG(Warning, "Failed to parse serialized scene objects data."); @@ -666,7 +672,10 @@ bool Prefab::ApplyAllInternal(Actor* targetActor, bool linkTargetActorObjectToPr newPrefabInstanceIdToDataIndex.EnsureCapacity(ObjectsCount * 4); { // Parse json to DOM document - diffDataDocument.Parse(dataBuffer.GetString(), dataBuffer.GetSize()); + { + PROFILE_CPU_NAMED("Json.Parse"); + diffDataDocument.Parse(dataBuffer.GetString(), dataBuffer.GetSize()); + } if (diffDataDocument.HasParseError()) { LOG(Warning, "Failed to parse serialized scene objects data."); diff --git a/Source/Engine/Level/Prefabs/PrefabManager.cpp b/Source/Engine/Level/Prefabs/PrefabManager.cpp index 77698e739..7cd62913d 100644 --- a/Source/Engine/Level/Prefabs/PrefabManager.cpp +++ b/Source/Engine/Level/Prefabs/PrefabManager.cpp @@ -372,7 +372,10 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat { // Parse json to DOM document rapidjson_flax::Document doc; - doc.Parse(actorsDataBuffer.GetString(), actorsDataBuffer.GetSize()); + { + PROFILE_CPU_NAMED("Json.Parse"); + doc.Parse(actorsDataBuffer.GetString(), actorsDataBuffer.GetSize()); + } if (doc.HasParseError()) { LOG(Warning, "Failed to parse serialized actors data."); diff --git a/Source/Engine/Scripting/Plugins/PluginManager.cs b/Source/Engine/Scripting/Plugins/PluginManager.cs index da0d7642d..6579b21da 100644 --- a/Source/Engine/Scripting/Plugins/PluginManager.cs +++ b/Source/Engine/Scripting/Plugins/PluginManager.cs @@ -85,18 +85,22 @@ namespace FlaxEngine #if FLAX_EDITOR internal static void InitializeGamePlugins() { + Profiler.BeginEvent("PluginManager.InitializeGamePlugins"); for (var i = 0; i < _gamePlugins.Count; i++) { InvokeInitialize(_gamePlugins[i]); } + Profiler.EndEvent(); } internal static void DeinitializeGamePlugins() { + Profiler.BeginEvent("PluginManager.DeinitializeGamePlugins"); for (var i = _gamePlugins.Count - 1; i >= 0; i--) { InvokeDeinitialize(_gamePlugins[i]); } + Profiler.EndEvent(); } #endif diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 715c1caf6..7744af2f3 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -259,7 +259,10 @@ bool Scripting::LoadBinaryModules(const String& path, const String& projectFolde // Parse Json data rapidjson_flax::Document document; - document.Parse((char*)fileData.Get(), fileData.Count()); + { + PROFILE_CPU_NAMED("Json.Parse"); + document.Parse((char*)fileData.Get(), fileData.Count()); + } if (document.HasParseError()) { LOG(Error, "Failed to file contents.");