From 1cef580cadf503ea83bf67110f9bc4390f58976b Mon Sep 17 00:00:00 2001 From: Guthrie Adams Date: Mon, 6 Dec 2021 17:12:06 -0600 Subject: [PATCH] Material editor asynchronously loads lighting and model presets changed several sequential blocking loads into asynchronous loads to improve material editor startup time Signed-off-by: Guthrie Adams --- .../Viewport/MaterialViewportComponent.cpp | 122 ++++++++---------- .../Viewport/MaterialViewportComponent.h | 12 ++ 2 files changed, 63 insertions(+), 71 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index c8df123d0d..35f5067cd0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -135,11 +134,19 @@ namespace MaterialEditor { AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); MaterialViewportRequestBus::Handler::BusDisconnect(); + ClearContent(); + } + void MaterialViewportComponent::ClearContent() + { + AZ::Data::AssetBus::MultiHandler::BusDisconnect(); + + m_lightingPresetAssets.clear(); m_lightingPresetVector.clear(); m_lightingPresetLastSavePathMap.clear(); m_lightingPresetSelection.reset(); + m_modelPresetAssets.clear(); m_modelPresetVector.clear(); m_modelPresetLastSavePathMap.clear(); m_modelPresetSelection.reset(); @@ -151,84 +158,36 @@ namespace MaterialEditor MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnBeginReloadContent); - const AZStd::string selectedLightingPresetNameOld = m_viewportSettings->m_selectedLightingPresetName; - - m_lightingPresetVector.clear(); - m_lightingPresetLastSavePathMap.clear(); - m_lightingPresetSelection.reset(); - - const AZStd::string selectedModelPresetNameOld = m_viewportSettings->m_selectedModelPresetName; - - m_modelPresetVector.clear(); - m_modelPresetLastSavePathMap.clear(); - m_modelPresetSelection.reset(); - - AZStd::vector lightingAssetInfoVector; - AZStd::vector modelAssetInfoVector; + ClearContent(); // Enumerate and load all the relevant preset files in the project. // (The files are stored in a temporary list instead of processed in the callback because deep operations inside // AssetCatalogRequestBus::EnumerateAssets can lead to deadlocked) - AZ::Data::AssetCatalogRequests::AssetEnumerationCB enumerateCB = [&lightingAssetInfoVector, &modelAssetInfoVector]([[maybe_unused]] const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info) + AZ::Data::AssetCatalogRequests::AssetEnumerationCB enumerateCB = [this]([[maybe_unused]] const AZ::Data::AssetId id, const AZ::Data::AssetInfo& info) { if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".lightingpreset.azasset")) { - lightingAssetInfoVector.push_back(info); + m_lightingPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType }; + AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId); } else if (AzFramework::StringFunc::EndsWith(info.m_relativePath.c_str(), ".modelpreset.azasset")) { - modelAssetInfoVector.push_back(info); + m_modelPresetAssets[info.m_assetId] = { info.m_assetId, info.m_assetType }; + AZ::Data::AssetBus::MultiHandler::BusConnect(info.m_assetId); } }; AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, enumerateCB, nullptr); - for (const auto& info : lightingAssetInfoVector) + for (auto& assetPair : m_lightingPresetAssets) { - if (info.m_assetId.IsValid()) - { - AZ::Data::Asset asset = AZ::RPI::AssetUtils::LoadAssetById( - info.m_assetId, AZ::RPI::AssetUtils::TraceLevel::Warning); - if (asset) - { - const AZ::Render::LightingPreset* preset = asset->GetDataAs(); - if (preset) - { - auto presetPtr = AddLightingPreset(*preset); - m_lightingPresetLastSavePathMap[presetPtr] = AZ::RPI::AssetUtils::GetSourcePathByAssetId(info.m_assetId); - AZ_TracePrintf("Material Editor", "Loaded viewport configuration: %s.\n", info.m_relativePath.c_str()); - } - } - } + assetPair.second.QueueLoad(); } - for (const auto& info : modelAssetInfoVector) + for (auto& assetPair : m_modelPresetAssets) { - if (info.m_assetId.IsValid()) - { - AZ::Data::Asset asset = - AZ::RPI::AssetUtils::LoadAssetById(info.m_assetId, AZ::RPI::AssetUtils::TraceLevel::Warning); - if (asset) - { - const AZ::Render::ModelPreset* preset = asset->GetDataAs(); - if (preset) - { - auto presetPtr = AddModelPreset(*preset); - m_modelPresetLastSavePathMap[presetPtr] = AZ::RPI::AssetUtils::GetSourcePathByAssetId(info.m_assetId); - AZ_TracePrintf("Material Editor", "Loaded viewport configuration: %s.\n", info.m_relativePath.c_str()); - } - } - } + assetPair.second.QueueLoad(); } - - // If there was a prior selection, this will keep the same configuration selected. - // Otherwise, these strings are empty and the operation will be ignored. - SelectLightingPresetByName(selectedLightingPresetNameOld); - SelectModelPresetByName(selectedModelPresetNameOld); - - MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnEndReloadContent); - - AZ_TracePrintf("Material Editor", "Finished loading viewport configurations.\n"); } AZ::Render::LightingPresetPtr MaterialViewportComponent::AddLightingPreset(const AZ::Render::LightingPreset& preset) @@ -237,12 +196,6 @@ namespace MaterialEditor auto presetPtr = m_lightingPresetVector.back(); MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnLightingPresetAdded, presetPtr); - - if (m_lightingPresetVector.size() == 1) - { - SelectLightingPreset(presetPtr); - } - return presetPtr; } @@ -314,12 +267,6 @@ namespace MaterialEditor auto presetPtr = m_modelPresetVector.back(); MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnModelPresetAdded, presetPtr); - - if (m_modelPresetVector.size() == 1) - { - SelectModelPreset(presetPtr); - } - return presetPtr; } @@ -443,6 +390,39 @@ namespace MaterialEditor return m_viewportSettings->m_displayMapperOperationType; } + inline void MaterialViewportComponent::OnAssetReady(AZ::Data::Asset asset) + { + if (AZ::Data::Asset anyAsset = asset) + { + if (const auto lightingPreset = anyAsset->GetDataAs()) + { + auto presetPtr = AddLightingPreset(*lightingPreset); + const auto& presetPath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(anyAsset.GetId()); + m_lightingPresetAssets[anyAsset.GetId()] = anyAsset; + m_lightingPresetLastSavePathMap[presetPtr] = presetPath; + AZ_TracePrintf("Material Editor", "Loaded Preset: %s\n", presetPath.c_str()); + } + + if (const auto modelPreset = anyAsset->GetDataAs()) + { + auto presetPtr = AddModelPreset(*modelPreset); + const auto& presetPath = AZ::RPI::AssetUtils::GetSourcePathByAssetId(anyAsset.GetId()); + m_modelPresetAssets[anyAsset.GetId()] = anyAsset; + m_modelPresetLastSavePathMap[presetPtr] = presetPath; + AZ_TracePrintf("Material Editor", "Loaded Preset: %s\n", presetPath.c_str()); + } + } + + AZ::Data::AssetBus::MultiHandler::BusDisconnect(asset.GetId()); + if (!AZ::Data::AssetBus::MultiHandler::BusIsConnected()) + { + SelectLightingPresetByName(m_viewportSettings->m_selectedLightingPresetName); + SelectModelPresetByName(m_viewportSettings->m_selectedModelPresetName); + MaterialViewportNotificationBus::Broadcast(&MaterialViewportNotificationBus::Events::OnEndReloadContent); + AZ_TracePrintf("Material Editor", "Finished loading viewport configurations.\n"); + } + } + void MaterialViewportComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) { AZ::TickBus::QueueFunction([this]() { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h index a4f94c3546..07385d842d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.h @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -22,6 +24,7 @@ namespace MaterialEditor class MaterialViewportComponent : public AZ::Component , private MaterialViewportRequestBus::Handler + , private AZ::Data::AssetBus::MultiHandler , private AzFramework::AssetCatalogEventBus::Handler { public: @@ -46,6 +49,8 @@ namespace MaterialEditor void Deactivate() override; //////////////////////////////////////////////////////////////////////// + void ClearContent(); + //////////////////////////////////////////////////////////////////////// // MaterialViewportRequestBus::Handler overrides ... void ReloadContent() override; @@ -82,14 +87,21 @@ namespace MaterialEditor AZ::Render::DisplayMapperOperationType GetDisplayMapperOperationType() const override; //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + // AZ::Data::AssetBus::MultiHandler overrides ... + void OnAssetReady(AZ::Data::Asset asset) override; + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// // AzFramework::AssetCatalogEventBus::Handler overrides ... void OnCatalogLoaded(const char* catalogFile) override; //////////////////////////////////////////////////////////////////////// + AZStd::unordered_map> m_lightingPresetAssets; AZ::Render::LightingPresetPtrVector m_lightingPresetVector; AZ::Render::LightingPresetPtr m_lightingPresetSelection; + AZStd::unordered_map> m_modelPresetAssets; AZ::Render::ModelPresetPtrVector m_modelPresetVector; AZ::Render::ModelPresetPtr m_modelPresetSelection;