/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "AssetMemoryAnalyzer_precompiled.h" #include #include #include #include #include "AssetMemoryAnalyzerSystemComponent.h" #include "AssetMemoryAnalyzer.h" #include "DebugImGUI.h" #include "ExportCSV.h" #include "ExportJSON.h" namespace AssetMemoryAnalyzer { namespace { static const char* GetExportFile(const char* customFilename, const char* extension) { static char sharedBuffer[AZ_MAX_PATH_LEN]; if (customFilename) { azsnprintf(sharedBuffer, sizeof(sharedBuffer), "@log@/%s", customFilename); } else { char timestampBuffer[64]; time_t ltime; time(<ime); struct tm timeInfo; AZ_TRAIT_CTIME_LOCALTIME(&timeInfo, <ime); strftime(timestampBuffer, sizeof(timestampBuffer), "@log@/assetmem-%Y-%m-%d-%H-%M-%S.%%s", &timeInfo); azsnprintf(sharedBuffer, sizeof(sharedBuffer), timestampBuffer, extension); } return sharedBuffer; } } static const char* VRAM_CATEGORIES[] = { "Texture", "Buffer", "Misc" }; static const char* VRAM_SUBCATEGORIES[] = { "Rendertarget", "Texture", "Dynamic", "VB", "IB", "CB", "Other", "Misc" }; class AssetMemoryAnalyzerSystemComponent::Impl { private: AZStd::unique_ptr m_analyzer; DebugImGUI m_debugImGUI; ExportCSV m_exportCSV; ExportJSON m_exportJSON; friend class AssetMemoryAnalyzerSystemComponent; }; AssetMemoryAnalyzerSystemComponent::AssetMemoryAnalyzerSystemComponent() : m_impl(new Impl) { AZ::AllocatorInstance::Create(); } AssetMemoryAnalyzerSystemComponent::~AssetMemoryAnalyzerSystemComponent() { m_impl.reset(); // Must delete objects before destroying the allocator AZ::AllocatorInstance::Destroy(); } void AssetMemoryAnalyzerSystemComponent::Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(0); if (AZ::EditContext* ec = serialize->GetEditContext()) { ec->Class("AssetMemoryAnalyzer", "Provides access to asset memory debugging features") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } } } void AssetMemoryAnalyzerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("AssetMemoryAnalyzerService", 0x23c52412)); } void AssetMemoryAnalyzerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("AssetMemoryAnalyzerService", 0x23c52412)); } void AssetMemoryAnalyzerSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) { (void)required; } void AssetMemoryAnalyzerSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) { (void)dependent; } const char** AssetMemoryAnalyzerSystemComponent::GetVRAMCategories() { return VRAM_CATEGORIES; } const char** AssetMemoryAnalyzerSystemComponent::GetVRAMSubCategories() { return VRAM_SUBCATEGORIES; } bool AssetMemoryAnalyzerSystemComponent::IsEnabled() const { return m_impl->m_analyzer.get() != nullptr; } AZStd::shared_ptr AssetMemoryAnalyzerSystemComponent::GetAnalysis() { AZStd::shared_ptr result; if (m_impl->m_analyzer) { result = m_impl->m_analyzer->GetAnalysis(); } return result; } void AssetMemoryAnalyzerSystemComponent::SetEnabled(bool enabled) { if (enabled) { if (!m_impl->m_analyzer) { m_impl->m_analyzer.reset(aznew Analyzer); } } else { m_impl->m_analyzer.reset(); } } void AssetMemoryAnalyzerSystemComponent::ExportCSVFile(const char* path) { const char* outputPath = GetExportFile(path, "csv"); m_impl->m_exportCSV.OutputCSV(outputPath); } void AssetMemoryAnalyzerSystemComponent::ExportJSONFile(const char* path) { const char* outputPath = GetExportFile(path, "json"); m_impl->m_exportJSON.OutputJSON(outputPath); } void AssetMemoryAnalyzerSystemComponent::Init() { static_assert(AZ_ARRAY_SIZE(VRAM_CATEGORIES) == Render::Debug::VRAMAllocationCategory::VRAM_CATEGORY_NUMBER_CATEGORIES, "VRAMAllocationCategory has changed length! Fix VRAM_CATEGORIES to match."); static_assert(AZ_ARRAY_SIZE(VRAM_SUBCATEGORIES) == Render::Debug::VRAMAllocationSubcategory::VRAM_SUBCATEGORY_NUMBER_SUBCATEGORIES, "VRAMAllocationSubcategory has changed length! Fix VRAM_SUBCATEGORIES to match."); m_impl->m_debugImGUI.Init(this); m_impl->m_exportCSV.Init(this); m_impl->m_exportJSON.Init(this); } void AssetMemoryAnalyzerSystemComponent::Activate() { AssetMemoryAnalyzerRequestBus::Handler::BusConnect(); } void AssetMemoryAnalyzerSystemComponent::Deactivate() { AssetMemoryAnalyzerRequestBus::Handler::BusDisconnect(); } }