From d4601ecb44cede2cb3650a442fb627bb76c1a040 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Fri, 9 Dec 2022 15:48:43 +0100 Subject: [PATCH] Add memory usage query for various asset types --- Source/Engine/Animations/AnimationData.h | 13 +++++++++++ Source/Engine/Animations/Curve.h | 5 +++++ Source/Engine/Content/Assets/Animation.cpp | 17 ++++++++++++++ Source/Engine/Content/Assets/Animation.h | 3 +-- Source/Engine/Content/Assets/RawDataAsset.cpp | 10 +++++++++ Source/Engine/Content/Assets/RawDataAsset.h | 4 ++++ Source/Engine/Content/BinaryAsset.cpp | 16 ++++++++++++++ Source/Engine/Content/BinaryAsset.h | 10 +-------- Source/Engine/Content/JsonAsset.cpp | 22 +++++++++++++++++++ Source/Engine/Content/JsonAsset.h | 5 +++++ .../Engine/Graphics/Textures/TextureBase.cpp | 15 +++++++++++++ Source/Engine/Graphics/Textures/TextureBase.h | 1 + Source/ThirdParty/rapidjson/document.h | 6 +++++ 13 files changed, 116 insertions(+), 11 deletions(-) diff --git a/Source/Engine/Animations/AnimationData.h b/Source/Engine/Animations/AnimationData.h index ad56e891a..082202f8a 100644 --- a/Source/Engine/Animations/AnimationData.h +++ b/Source/Engine/Animations/AnimationData.h @@ -86,6 +86,11 @@ public: { return Position.GetKeyframes().Count() + Rotation.GetKeyframes().Count() + Scale.GetKeyframes().Count(); } + + uint64 GetMemoryUsage() const + { + return NodeName.Length() * sizeof(Char) + Position.GetMemoryUsage() + Rotation.GetMemoryUsage() + Scale.GetMemoryUsage(); + } }; /// @@ -131,6 +136,14 @@ public: return static_cast(Duration / FramesPerSecond); } + uint64 GetMemoryUsage() const + { + uint64 result = RootNodeName.Length() * sizeof(Char) + Channels.Capacity() * sizeof(NodeAnimationData); + for (const auto& e : Channels) + result += e.GetMemoryUsage(); + return result; + } + /// /// Gets the total amount of keyframes in the all animation channels. /// diff --git a/Source/Engine/Animations/Curve.h b/Source/Engine/Animations/Curve.h index 8d91960e6..7105a6bdf 100644 --- a/Source/Engine/Animations/Curve.h +++ b/Source/Engine/Animations/Curve.h @@ -733,6 +733,11 @@ public: _keyframes[i].Time = _keyframes[i].Time * timeScale + timeOffset;; } + uint64 GetMemoryUsage() const + { + return _keyframes.Capacity() * sizeof(KeyFrame); + } + public: FORCE_INLINE KeyFrame& operator[](int32 index) { diff --git a/Source/Engine/Content/Assets/Animation.cpp b/Source/Engine/Content/Assets/Animation.cpp index c6ece7b3f..65a96a5fa 100644 --- a/Source/Engine/Content/Assets/Animation.cpp +++ b/Source/Engine/Content/Assets/Animation.cpp @@ -569,6 +569,23 @@ void Animation::OnSkinnedModelUnloaded(Asset* obj) MappingCache.Remove(i); } +uint64 Animation::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = BinaryAsset::GetMemoryUsage(); + result += sizeof(Animation) - sizeof(BinaryAsset); + result += Data.GetMemoryUsage(); + result += Events.Capacity() * sizeof(Pair>); + for (const auto& e : Events) + result += e.First.Length() * sizeof(Char) + e.Second.GetMemoryUsage(); + result += NestedAnims.Capacity() * sizeof(Pair); + result += MappingCache.Capacity() * sizeof(Pair>); + for (const auto& e : MappingCache) + result += e.Value.Capacity() * sizeof(int32); + Locker.Unlock(); + return result; +} + void Animation::OnScriptingDispose() { // Dispose any events to prevent crashes (scripting is released before content) diff --git a/Source/Engine/Content/Assets/Animation.h b/Source/Engine/Content/Assets/Animation.h index 826f60c1d..ca1d3373d 100644 --- a/Source/Engine/Content/Assets/Animation.h +++ b/Source/Engine/Content/Assets/Animation.h @@ -152,7 +152,6 @@ public: const NodeToChannel* GetMapping(SkinnedModel* obj); #if USE_EDITOR - /// /// Gets the animation as serialized timeline data. Used to show it in Editor. /// @@ -173,7 +172,6 @@ public: /// The cannot be used by virtual assets. /// true failed to save data; otherwise, false. bool Save(const StringView& path = StringView::Empty); - #endif private: @@ -181,6 +179,7 @@ private: public: // [BinaryAsset] + uint64 GetMemoryUsage() const override; void OnScriptingDispose() override; protected: diff --git a/Source/Engine/Content/Assets/RawDataAsset.cpp b/Source/Engine/Content/Assets/RawDataAsset.cpp index 1b39572e4..f16b267e1 100644 --- a/Source/Engine/Content/Assets/RawDataAsset.cpp +++ b/Source/Engine/Content/Assets/RawDataAsset.cpp @@ -64,6 +64,16 @@ bool RawDataAsset::Save(const StringView& path) #endif +uint64 RawDataAsset::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = BinaryAsset::GetMemoryUsage(); + result += sizeof(RawDataAsset) - sizeof(BinaryAsset); + result += Data.Count(); + Locker.Unlock(); + return result; +} + Asset::LoadResult RawDataAsset::load() { auto chunk0 = GetChunk(0); diff --git a/Source/Engine/Content/Assets/RawDataAsset.h b/Source/Engine/Content/Assets/RawDataAsset.h index 2558426e9..65aa37eb1 100644 --- a/Source/Engine/Content/Assets/RawDataAsset.h +++ b/Source/Engine/Content/Assets/RawDataAsset.h @@ -28,6 +28,10 @@ public: #endif +public: + // [BinaryAsset] + uint64 GetMemoryUsage() const override; + protected: // [BinaryAsset] LoadResult load() override; diff --git a/Source/Engine/Content/BinaryAsset.cpp b/Source/Engine/Content/BinaryAsset.cpp index 3b268f72e..99c91cc4a 100644 --- a/Source/Engine/Content/BinaryAsset.cpp +++ b/Source/Engine/Content/BinaryAsset.cpp @@ -452,6 +452,22 @@ const String& BinaryAsset::GetPath() const #endif } +uint64 BinaryAsset::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = Asset::GetMemoryUsage(); + result += sizeof(BinaryAsset) - sizeof(Asset); + result += _dependantAssets.Capacity() * sizeof(BinaryAsset*); + for (int32 i = 0; i < ASSET_FILE_DATA_CHUNKS; i++) + { + auto chunk = _header.Chunks[i]; + if (chunk != nullptr && chunk->IsLoaded()) + result += chunk->Size(); + } + Locker.Unlock(); + return result; +} + /// /// Helper task used to initialize binary asset and upgrade it if need to in background. /// diff --git a/Source/Engine/Content/BinaryAsset.h b/Source/Engine/Content/BinaryAsset.h index e98c645fe..fb96db6f6 100644 --- a/Source/Engine/Content/BinaryAsset.h +++ b/Source/Engine/Content/BinaryAsset.h @@ -41,7 +41,6 @@ public: FlaxStorage* Storage; #if USE_EDITOR - /// /// The asset metadata information. Stored in a Json format. /// @@ -51,14 +50,12 @@ public: /// Asset dependencies list used by the asset for tracking (eg. material functions used by material asset). The pair of asset ID and cached file edit time (for tracking modification). /// Array> Dependencies; - #endif public: /// /// Gets the asset serialized version. /// - /// Version number. virtual uint32 GetSerializedVersion() const = 0; /// @@ -84,14 +81,11 @@ public: public: #if USE_EDITOR - #if COMPILE_WITH_ASSETS_IMPORTER - /// /// Reimports asset from the source file. /// API_FUNCTION() void Reimport() const; - #endif /// @@ -130,7 +124,6 @@ protected: virtual void OnDependencyModified(BinaryAsset* asset) { } - #endif protected: @@ -255,7 +248,6 @@ public: bool LoadChunks(AssetChunksFlag chunks); #if USE_EDITOR - /// /// Saves this asset to the storage container. /// @@ -281,7 +273,6 @@ public: /// In silent mode don't reload opened storage container that is using target file. /// True if failed, otherwise false. static bool SaveToAsset(const StringView& path, AssetInitData& data, bool silentMode = false); - #endif protected: @@ -302,6 +293,7 @@ public: void OnDeleteObject() override; #endif const String& GetPath() const final override; + uint64 GetMemoryUsage() const override; protected: // [Asset] diff --git a/Source/Engine/Content/JsonAsset.cpp b/Source/Engine/Content/JsonAsset.cpp index 4725f1ce9..9928f00e4 100644 --- a/Source/Engine/Content/JsonAsset.cpp +++ b/Source/Engine/Content/JsonAsset.cpp @@ -93,6 +93,17 @@ const String& JsonAssetBase::GetPath() const #endif } +uint64 JsonAssetBase::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = Asset::GetMemoryUsage(); + result += sizeof(JsonAssetBase) - sizeof(Asset); + if (Data) + result += Document.GetAllocator().Capacity(); + Locker.Unlock(); + return result; +} + #if USE_EDITOR void FindIds(ISerializable::DeserializeStream& node, Array& output) @@ -248,6 +259,17 @@ JsonAsset::JsonAsset(const SpawnParams& params, const AssetInfo* info) { } +uint64 JsonAsset::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = JsonAssetBase::GetMemoryUsage(); + result += sizeof(JsonAsset) - sizeof(JsonAssetBase); + if (Instance && InstanceType) + result += InstanceType.GetType().Size; + Locker.Unlock(); + return result; +} + Asset::LoadResult JsonAsset::loadAsset() { const auto result = JsonAssetBase::loadAsset(); diff --git a/Source/Engine/Content/JsonAsset.h b/Source/Engine/Content/JsonAsset.h index 5f2862abc..b8f4a9b50 100644 --- a/Source/Engine/Content/JsonAsset.h +++ b/Source/Engine/Content/JsonAsset.h @@ -77,6 +77,7 @@ public: public: // [Asset] const String& GetPath() const override; + uint64 GetMemoryUsage() const override; #if USE_EDITOR void GetReferences(Array& output) const override; #endif @@ -122,6 +123,10 @@ public: return Instance && InstanceType.IsAssignableFrom(T::TypeInitializer) ? (T*)Instance : nullptr; } +public: + // [JsonAssetBase] + uint64 GetMemoryUsage() const override; + protected: // [JsonAssetBase] LoadResult loadAsset() override; diff --git a/Source/Engine/Graphics/Textures/TextureBase.cpp b/Source/Engine/Graphics/Textures/TextureBase.cpp index fbd85830e..a4d458730 100644 --- a/Source/Engine/Graphics/Textures/TextureBase.cpp +++ b/Source/Engine/Graphics/Textures/TextureBase.cpp @@ -636,6 +636,21 @@ bool TextureBase::Init(void* ptr) return Init(initData); } +uint64 TextureBase::GetMemoryUsage() const +{ + Locker.Lock(); + uint64 result = BinaryAsset::GetMemoryUsage(); + result += sizeof(TextureBase) - sizeof(BinaryAsset); + if (_customData) + { + result += sizeof(InitData); + for (auto& mip : _customData->Mips) + result += mip.Data.Length(); + } + Locker.Unlock(); + return result; +} + void TextureBase::CancelStreaming() { _texture.CancelStreamingTasks(); diff --git a/Source/Engine/Graphics/Textures/TextureBase.h b/Source/Engine/Graphics/Textures/TextureBase.h index 857d03085..cc0e4b548 100644 --- a/Source/Engine/Graphics/Textures/TextureBase.h +++ b/Source/Engine/Graphics/Textures/TextureBase.h @@ -221,6 +221,7 @@ private: public: // [BinaryAsset] + uint64 GetMemoryUsage() const override; void CancelStreaming() override; // [ITextureOwner] diff --git a/Source/ThirdParty/rapidjson/document.h b/Source/ThirdParty/rapidjson/document.h index f52e969ab..f09f11d40 100644 --- a/Source/ThirdParty/rapidjson/document.h +++ b/Source/ThirdParty/rapidjson/document.h @@ -2304,6 +2304,12 @@ public: return *allocator_; } + //! Get the allocator of this document. + const Allocator& GetAllocator() const { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + //! Get the capacity of stack in bytes. size_t GetStackCapacity() const { return stack_.GetCapacity(); }