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 <guthadam@amazon.com>
This commit is contained in:
@@ -9,7 +9,6 @@
|
||||
#include <Atom/RPI.Edit/Common/AssetUtils.h>
|
||||
#include <Atom/RPI.Edit/Common/JsonUtils.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <Atom/Viewport/MaterialViewportNotificationBus.h>
|
||||
#include <Atom/Viewport/MaterialViewportSettings.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
@@ -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<AZ::Data::AssetInfo> lightingAssetInfoVector;
|
||||
AZStd::vector<AZ::Data::AssetInfo> 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<AZ::RPI::AnyAsset> asset = AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::AnyAsset>(
|
||||
info.m_assetId, AZ::RPI::AssetUtils::TraceLevel::Warning);
|
||||
if (asset)
|
||||
{
|
||||
const AZ::Render::LightingPreset* preset = asset->GetDataAs<AZ::Render::LightingPreset>();
|
||||
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<AZ::RPI::AnyAsset> asset =
|
||||
AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::AnyAsset>(info.m_assetId, AZ::RPI::AssetUtils::TraceLevel::Warning);
|
||||
if (asset)
|
||||
{
|
||||
const AZ::Render::ModelPreset* preset = asset->GetDataAs<AZ::Render::ModelPreset>();
|
||||
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<AZ::Data::AssetData> asset)
|
||||
{
|
||||
if (AZ::Data::Asset<AZ::RPI::AnyAsset> anyAsset = asset)
|
||||
{
|
||||
if (const auto lightingPreset = anyAsset->GetDataAs<AZ::Render::LightingPreset>())
|
||||
{
|
||||
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<AZ::Render::ModelPreset>())
|
||||
{
|
||||
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]() {
|
||||
|
||||
@@ -11,8 +11,10 @@
|
||||
#include <ACES/Aces.h>
|
||||
#include <Atom/Feature/Utils/LightingPreset.h>
|
||||
#include <Atom/Feature/Utils/ModelPreset.h>
|
||||
#include <Atom/RPI.Reflect/System/AnyAsset.h>
|
||||
#include <Atom/Viewport/MaterialViewportRequestBus.h>
|
||||
#include <Atom/Viewport/MaterialViewportSettings.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
|
||||
@@ -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<AZ::Data::AssetData> asset) override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// AzFramework::AssetCatalogEventBus::Handler overrides ...
|
||||
void OnCatalogLoaded(const char* catalogFile) override;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::RPI::AnyAsset>> m_lightingPresetAssets;
|
||||
AZ::Render::LightingPresetPtrVector m_lightingPresetVector;
|
||||
AZ::Render::LightingPresetPtr m_lightingPresetSelection;
|
||||
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::RPI::AnyAsset>> m_modelPresetAssets;
|
||||
AZ::Render::ModelPresetPtrVector m_modelPresetVector;
|
||||
AZ::Render::ModelPresetPtr m_modelPresetSelection;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user