Browse Source

Fixed TIAF failures, unreleased assets on shutdown, preexisting thumbnail crash that occasionally happened on shutdown

Signed-off-by: Guthrie Adams <[email protected]>
Signed-off-by: Alex Peterson <[email protected]>

# Conflicts:
#	Gems/Atom/Tools/MaterialCanvas/Code/Source/MaterialCanvasApplication.cpp
Guthrie Adams 1 year ago
parent
commit
f5e7767a53

+ 22 - 19
Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerComponent.cpp

@@ -26,16 +26,13 @@ namespace AzToolsFramework
         ThumbnailerComponent::ThumbnailerComponent()
             : m_missingThumbnail(new MissingThumbnail())
             , m_loadingThumbnail(new LoadingThumbnail())
+            , m_placeholderObject(new QObject())
         {
         }
 
         ThumbnailerComponent::~ThumbnailerComponent()
         {
-            ThumbnailerRequestBus::Handler::BusDisconnect();
-            m_providers.clear();
-            m_missingThumbnail.reset();
-            m_loadingThumbnail.reset();
-            m_thumbnailsBeingLoaded.clear();
+            Cleanup();
         }
 
         void ThumbnailerComponent::Activate()
@@ -45,11 +42,7 @@ namespace AzToolsFramework
 
         void ThumbnailerComponent::Deactivate()
         {
-            ThumbnailerRequestBus::Handler::BusDisconnect();
-            m_providers.clear();
-            m_missingThumbnail.reset();
-            m_loadingThumbnail.reset();
-            m_thumbnailsBeingLoaded.clear();
+            Cleanup();
         }
 
         void ThumbnailerComponent::Reflect(AZ::ReflectContext* context)
@@ -130,25 +123,29 @@ namespace AzToolsFramework
                         // Connect thumbnailer component to the busy label repaint signal to notify the asset browser as it changes. 
                         AzQtComponents::StyledBusyLabel* busyLabel = {};
                         AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult(busyLabel, &AssetBrowser::AssetBrowserComponentRequests::GetStyledBusyLabel);
-                        connect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, this, &ThumbnailerComponent::RepaintThumbnail);
+                        QObject::connect(busyLabel, &AzQtComponents::StyledBusyLabel::repaintNeeded, m_placeholderObject.get(), [](){
+                            AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AssetBrowser::AssetBrowserViewRequests::Update);
+                        });
 
                         // The ThumbnailUpdated signal should be sent whenever the thumbnail has loaded or failed. In both cases,
                         // disconnect from all of the signals.
-                        connect(thumbnail.data(), &Thumbnail::ThumbnailUpdated, this, [this, key, thumbnail, busyLabel]()
+                        QObject::connect(thumbnail.data(), &Thumbnail::ThumbnailUpdated, m_placeholderObject.get(), [this, key, thumbnail, busyLabel]()
                             {
-                                disconnect(busyLabel, nullptr, this, nullptr);
-                                disconnect(thumbnail.data(), &Thumbnail::ThumbnailUpdated, key.data(), &ThumbnailKey::ThumbnailUpdated);
+                                QObject::disconnect(busyLabel, nullptr, m_placeholderObject.get(), nullptr);
+                                QObject::disconnect(thumbnail.data(), nullptr, key.data(), nullptr);
+
+                                QObject::connect(thumbnail.data(), &Thumbnail::ThumbnailUpdated, key.data(), &ThumbnailKey::ThumbnailUpdated);
+                                QObject::connect(key.data(), &ThumbnailKey::ThumbnailUpdateRequested, thumbnail.data(), &Thumbnail::Update);
 
-                                connect(thumbnail.data(), &Thumbnail::ThumbnailUpdated, key.data(), &ThumbnailKey::ThumbnailUpdated);
-                                connect(key.data(), &ThumbnailKey::ThumbnailUpdateRequested, thumbnail.data(), &Thumbnail::Update);
                                 key->SetReady(true);
                                 m_thumbnailsBeingLoaded.erase(thumbnail);
+                                AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AssetBrowser::AssetBrowserViewRequests::Update);
                             });
 
                         // Add the thumbnail to the set of thumbnails in progress then queue the job to load it. The job will send the
                         // ThumbnailUpdated signal from the main thread when complete.
                         m_thumbnailsBeingLoaded.insert(thumbnail);
-                        auto job = AZ::CreateJobFunction([thumbnail]() { thumbnail->Load(); }, true);
+                        auto job = AZ::CreateJobFunction([thumbnail](){ thumbnail->Load(); }, true);
                         job->Start();
                     }
 
@@ -172,9 +169,15 @@ namespace AzToolsFramework
             return false;
         }
 
-        void ThumbnailerComponent::RepaintThumbnail()
+        void ThumbnailerComponent::Cleanup()
         {
-            AssetBrowser::AssetBrowserViewRequestBus::Broadcast(&AssetBrowser::AssetBrowserViewRequests::Update);
+            ThumbnailerRequestBus::Handler::BusDisconnect();
+
+            m_providers.clear();
+            m_missingThumbnail.reset();
+            m_loadingThumbnail.reset();
+            m_placeholderObject.reset();
+            m_thumbnailsBeingLoaded.clear();
         }
     } // namespace Thumbnailer
 } // namespace AzToolsFramework

+ 4 - 5
Code/Framework/AzToolsFramework/AzToolsFramework/Thumbnails/ThumbnailerComponent.h

@@ -14,9 +14,7 @@
 #include <AzToolsFramework/Thumbnails/Thumbnail.h>
 #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
 
-#include <QList>
 #include <QObject>
-#include <QThreadPool>
 #endif
 
 class QString;
@@ -29,7 +27,6 @@ namespace AzToolsFramework
         class ThumbnailerComponent
             : public AZ::Component
             , public ThumbnailerRequestBus::Handler
-            , public QObject
         {
         public:
             AZ_COMPONENT(ThumbnailerComponent, "{80090CA5-6A3A-4554-B5FE-A6D74ECB2D84}")
@@ -50,9 +47,9 @@ namespace AzToolsFramework
             SharedThumbnail GetThumbnail(SharedThumbnailKey thumbnailKey) override;
             bool IsLoading(SharedThumbnailKey thumbnailKey) override;
 
-            void RepaintThumbnail();
-
         private:
+            void Cleanup();
+
             struct ProviderCompare
             {
                 bool operator()(const SharedThumbnailProvider& lhs, const SharedThumbnailProvider& rhs) const
@@ -68,6 +65,8 @@ namespace AzToolsFramework
             SharedThumbnail m_missingThumbnail;
             //! Default loading thumbnail used when thumbnail is found by is not yet generated
             SharedThumbnail m_loadingThumbnail;
+            //! Using placeholder object rather than inheritance for connecting signals and slots
+            AZStd::unique_ptr<QObject> m_placeholderObject;
             //! Current number of jobs running.
             AZStd::set<SharedThumbnail> m_thumbnailsBeingLoaded;
         };

+ 6 - 3
Gems/Atom/Feature/Common/Code/Source/CoreLights/CoreLightsSystemComponent.cpp

@@ -90,17 +90,17 @@ namespace AZ
 
         void CoreLightsSystemComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
         {
-            provided.push_back(AZ_CRC("CoreLightsService", 0x91932ef6));
+            provided.push_back(AZ_CRC_CE("CoreLightsService"));
         }
 
         void CoreLightsSystemComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
         {
-            incompatible.push_back(AZ_CRC("CoreLightsService", 0x91932ef6));
+            incompatible.push_back(AZ_CRC_CE("CoreLightsService"));
         }
 
         void CoreLightsSystemComponent::GetRequiredServices(ComponentDescriptor::DependencyArrayType& required)
         {
-            required.push_back(AZ_CRC("RPISystem", 0xf2add773));
+            required.push_back(AZ_CRC_CE("RPISystem"));
         }
 
         void CoreLightsSystemComponent::Init()
@@ -109,6 +109,8 @@ namespace AZ
 
         void CoreLightsSystemComponent::Activate()
         {
+            m_ltcCommonInterface.reset(aznew LtcCommon());
+
             AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessorWithInterface<SimplePointLightFeatureProcessor, SimplePointLightFeatureProcessorInterface>();
             AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessorWithInterface<SimpleSpotLightFeatureProcessor, SimpleSpotLightFeatureProcessorInterface>();
             AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessorWithInterface<PointLightFeatureProcessor, PointLightFeatureProcessorInterface>();
@@ -132,6 +134,7 @@ namespace AZ
 
         void CoreLightsSystemComponent::Deactivate()
         {
+            m_ltcCommonInterface.reset();
         }
     } // namespace Render
 } // namespace AZ

+ 1 - 1
Gems/Atom/Feature/Common/Code/Source/CoreLights/CoreLightsSystemComponent.h

@@ -33,7 +33,7 @@ namespace AZ
             void Activate() override;
             void Deactivate() override;
 
-            LtcCommon m_ltcCommonInterface;
+           AZStd::unique_ptr<LtcCommon> m_ltcCommonInterface;
         };
     } // namespace Render
 } // namespace AZ

+ 3 - 2
Gems/Atom/Feature/Common/Code/Source/CoreLights/LtcCommon.cpp

@@ -12,8 +12,8 @@
 
 namespace AZ::Render
 {
-    static const char* s_LtcGgxMatrixPath = "textures/ltc/ltc_mat_lutrgba32f.dds.streamingimage";
-    static const char* s_LtcGgxAmplificationPath = "textures/ltc/ltc_amp_lutrg32f.dds.streamingimage";
+    static constexpr const char* s_LtcGgxMatrixPath = "textures/ltc/ltc_mat_lutrgba32f.dds.streamingimage";
+    static constexpr const char* s_LtcGgxAmplificationPath = "textures/ltc/ltc_amp_lutrg32f.dds.streamingimage";
 
     LtcCommon::LtcCommon()
     {
@@ -22,6 +22,7 @@ namespace AZ::Render
 
     LtcCommon::~LtcCommon()
     {
+        m_assetLoaders.clear();
         Interface<ILtcCommon>::Unregister(this);
     }
 

+ 2 - 1
Gems/Atom/RPI/Code/Include/Atom/RPI.Reflect/Asset/AssetUtils.inl

@@ -56,7 +56,8 @@ namespace AZ
                     return;
                 }
 
-                m_asset.Create(assetId, AZ::Data::AssetLoadBehavior::PreLoad, true);
+                m_asset = AZ::Data::AssetManager::Instance().GetAsset<AssetDataT>(assetId, AZ::Data::AssetLoadBehavior::PreLoad);
+                m_asset.QueueLoad();
                 Data::AssetBus::Handler::BusConnect(assetId);
             }
         } // namespace AssetUtils

+ 2 - 0
Gems/GraphModel/Code/Include/GraphModel/Model/Slot.h

@@ -73,6 +73,8 @@ namespace GraphModel
             return AZStd::string::format("GraphModelSlotId(%s,%d)", m_name.c_str(), m_subId);
         }
 
+        AZStd::string ToString() const;
+
         SlotName m_name;
         SlotSubId m_subId = 0;
     };

+ 5 - 0
Gems/GraphModel/Code/Source/Model/Slot.cpp

@@ -120,6 +120,11 @@ namespace GraphModel
         return result;
     }
 
+    AZStd::string SlotId::ToString() const
+    {
+        return AZStd::string::format("GraphModelSlotId(%s,%d)", m_name.c_str(), m_subId);
+    }
+
     /////////////////////////////////////////////////////////
     // SlotDefinition