Fix for LYN-4594: [Atom][EMFX] Loading a saved level with entity and an actor component causes the editor to freeze. (DCO fixup) (#1878)
* Queue shader loads and register with the dynamic draw context after the shader is loaded to avoid a deadlock when there are multiple scenes processing at the same time. Signed-off-by: amzn-tommy <waltont@amazon.com> * Fixed AzCore case in AtomFont.h and two other files I found while searching Signed-off-by: amzn-tommy <waltont@amazon.com> * Switched to a utility that will both get the assetId and create the Asset, without calling GetAsset explicitely Signed-off-by: amzn-tommy <waltont@amazon.com> * Fixing typos in error message Signed-off-by: amzn-tommy <waltont@amazon.com>
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/smart_ptr/weak_ptr.h>
|
||||
#include <AzCore/std/parallel/shared_mutex.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <map>
|
||||
|
||||
#include <AzFramework/Font/FontInterface.h>
|
||||
@@ -38,6 +39,7 @@ namespace AZ
|
||||
class AtomFont
|
||||
: public ICryFont
|
||||
, public AzFramework::FontQueryInterface
|
||||
, private Data::AssetBus::Handler
|
||||
{
|
||||
friend class FFont;
|
||||
|
||||
@@ -122,6 +124,9 @@ namespace AZ
|
||||
//! \param outputFullPath Full path to loaded font family, may need resolving with PathUtil::MakeGamePath.
|
||||
XmlNodeRef LoadFontFamilyXml(const char* fontFamilyName, string& outputDirectory, string& outputFullPath);
|
||||
|
||||
// Data::AssetBus::Handler overrides...
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
|
||||
private:
|
||||
AzFramework::ISceneSystem::SceneEvent::Handler m_sceneEventHandler;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
|
||||
// Static member definitions
|
||||
const AZ::AtomFont::GlyphSize AZ::AtomFont::defaultGlyphSize = AZ::AtomFont::GlyphSize(ICryFont::defaultGlyphSizeX, ICryFont::defaultGlyphSizeY);
|
||||
@@ -349,30 +350,18 @@ AZ::AtomFont::AtomFont(ISystem* system)
|
||||
#endif
|
||||
AZ::Interface<AzFramework::FontQueryInterface>::Register(this);
|
||||
|
||||
// register font per viewport dynamic draw context.
|
||||
// Queue a load for the font per viewport dynamic draw context shader, and wait for it to load
|
||||
static const char* shaderFilepath = "Shaders/SimpleTextured.azshader";
|
||||
AZ::AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(
|
||||
AZ::Name(AZ::AtomFontDynamicDrawContextName),
|
||||
[](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
{
|
||||
Data::Instance<RPI::Shader> shader = AZ::RPI::LoadShader(shaderFilepath);
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("false")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true")));
|
||||
drawContext->InitShaderWithVariant(shader, &shaderOptions);
|
||||
drawContext->InitVertexFormat(
|
||||
{
|
||||
{"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::B8G8R8A8_UNORM},
|
||||
{"TEXCOORD0", RHI::Format::R32G32_FLOAT}
|
||||
});
|
||||
drawContext->EndInit();
|
||||
});
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ShaderAsset>(shaderFilepath, RPI::AssetUtils::TraceLevel::Assert);
|
||||
shaderAsset.QueueLoad();
|
||||
Data::AssetBus::Handler::BusConnect(shaderAsset.GetId());
|
||||
|
||||
}
|
||||
|
||||
AZ::AtomFont::~AtomFont()
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
|
||||
AZ::Interface<AzFramework::FontQueryInterface>::Unregister(this);
|
||||
m_defaultFontDrawInterface = nullptr;
|
||||
|
||||
@@ -864,5 +853,36 @@ XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, string& o
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
void AZ::AtomFont::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = asset;
|
||||
|
||||
AZ::AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(
|
||||
AZ::Name(AZ::AtomFontDynamicDrawContextName),
|
||||
[shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
{
|
||||
AZ_Assert(shaderAsset->IsReady(), "Attempting to register the AtomFont"
|
||||
" dynamic draw context before the shader asset is loaded. The shader should be loaded first"
|
||||
" to avoid a blocking asset load and potential deadlock, since the DynamicDrawContext lambda"
|
||||
" will be executed during scene processing and there may be multiple scenes executing in parallel.");
|
||||
|
||||
Data::Instance<RPI::Shader> shader = RPI::Shader::FindOrCreate(shaderAsset);
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("false")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true")));
|
||||
drawContext->InitShaderWithVariant(shader, &shaderOptions);
|
||||
drawContext->InitVertexFormat(
|
||||
{
|
||||
{"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::B8G8R8A8_UNORM},
|
||||
{"TEXCOORD0", RHI::Format::R32G32_FLOAT}
|
||||
});
|
||||
drawContext->EndInit();
|
||||
});
|
||||
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+29
-10
@@ -27,6 +27,7 @@
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
#include <Atom/RPI.Reflect/Image/StreamingImageAssetCreator.h>
|
||||
#include <Atom/RPI.Reflect/Image/ImageMipChainAssetCreator.h>
|
||||
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImagePool.h>
|
||||
|
||||
#include <AtomBridge/PerViewportDynamicDrawInterface.h>
|
||||
@@ -87,6 +88,7 @@ namespace AZ::Render
|
||||
|
||||
void AtomViewportDisplayIconsSystemComponent::Deactivate()
|
||||
{
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
Bootstrap::NotificationBus::Handler::BusDisconnect();
|
||||
|
||||
auto perViewportDynamicDrawInterface = AtomBridge::PerViewportDynamicDraw::Get();
|
||||
@@ -338,15 +340,32 @@ namespace AZ::Render
|
||||
|
||||
void AtomViewportDisplayIconsSystemComponent::OnBootstrapSceneReady([[maybe_unused]]AZ::RPI::Scene* bootstrapScene)
|
||||
{
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
{
|
||||
auto shader = RPI::LoadShader(DrawContextShaderPath);
|
||||
drawContext->InitShader(shader);
|
||||
drawContext->InitVertexFormat(
|
||||
{{"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::R8G8B8A8_UNORM},
|
||||
{"TEXCOORD", RHI::Format::R32G32_FLOAT}});
|
||||
drawContext->EndInit();
|
||||
});
|
||||
// Queue a load for the draw context shader, and wait for it to load
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ShaderAsset>(DrawContextShaderPath, RPI::AssetUtils::TraceLevel::Assert);
|
||||
shaderAsset.QueueLoad();
|
||||
Data::AssetBus::Handler::BusConnect(shaderAsset.GetId());
|
||||
}
|
||||
|
||||
void AtomViewportDisplayIconsSystemComponent::OnAssetReady(Data::Asset<Data::AssetData> asset)
|
||||
{
|
||||
// Once the shader is loaded, register it with the dynamic draw context
|
||||
Data::Asset<RPI::ShaderAsset> shaderAsset = asset;
|
||||
AtomBridge::PerViewportDynamicDraw::Get()->RegisterDynamicDrawContext(m_drawContextName, [shaderAsset](RPI::Ptr<RPI::DynamicDrawContext> drawContext)
|
||||
{
|
||||
AZ_Assert(shaderAsset->IsReady(), "Attempting to register the AtomViewportDisplayIconsSystemComponent"
|
||||
" dynamic draw context before the shader asset is loaded. The shader should be loaded first"
|
||||
" to avoid a blocking asset load and potential deadlock, since the DynamicDrawContext lambda"
|
||||
" will be executed during scene processing and there may be multiple scenes executing in parallel.");
|
||||
|
||||
Data::Instance<RPI::Shader> shader = RPI::Shader::FindOrCreate(shaderAsset);
|
||||
drawContext->InitShader(shader);
|
||||
drawContext->InitVertexFormat(
|
||||
{ {"POSITION", RHI::Format::R32G32B32_FLOAT},
|
||||
{"COLOR", RHI::Format::R8G8B8A8_UNORM},
|
||||
{"TEXCOORD", RHI::Format::R32G32_FLOAT} });
|
||||
drawContext->EndInit();
|
||||
});
|
||||
|
||||
Data::AssetBus::Handler::BusDisconnect();
|
||||
}
|
||||
} // namespace AZ::Render
|
||||
|
||||
+4
@@ -27,6 +27,7 @@ namespace AZ
|
||||
: public AZ::Component
|
||||
, public AzToolsFramework::EditorViewportIconDisplayInterface
|
||||
, public AZ::Render::Bootstrap::NotificationBus::Handler
|
||||
, private Data::AssetBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(AtomViewportDisplayIconsSystemComponent, "{AEC1D3E1-1D9A-437A-B4C6-CFAEE620C160}");
|
||||
@@ -51,6 +52,9 @@ namespace AZ
|
||||
// AZ::Render::Bootstrap::NotificationBus::Handler overrides...
|
||||
void OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) override;
|
||||
|
||||
// Data::AssetBus::Handler overrides...
|
||||
void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
|
||||
|
||||
private:
|
||||
static constexpr const char* DrawContextShaderPath = "Shaders/TexturedIcon.azshader";
|
||||
static constexpr QSize MinimumRenderedSvgSize = QSize(128, 128);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <IRenderAuxGeom.h>
|
||||
#include <Azcore/Math/Color.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
|
||||
namespace Blast
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <Atom/Feature/Mesh/MeshFeatureProcessorInterface.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <Azcore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
|
||||
namespace Blast
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user