From 9f034b90a2f405748926d480d1101d2f48e27d08 Mon Sep 17 00:00:00 2001 From: yuriy0 Date: Fri, 25 Jun 2021 12:43:16 -0400 Subject: [PATCH] Generate texture thumbnails in a job thread (#1571) Signed-off-by: John --- .../ImageThumbnailSystemComponent.cpp | 90 +++++++++++-------- .../Thumbnail/ImageThumbnailSystemComponent.h | 5 +- 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.cpp index 1af6563577..5a8bd4df14 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -115,8 +116,7 @@ namespace ImageProcessingAtom void ImageThumbnailSystemComponent::RenderThumbnail( AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize) { - auto sourceKey = azrtti_cast(thumbnailKey.data()); - if (sourceKey) + if (auto sourceKey = azrtti_cast(thumbnailKey.data())) { bool foundIt = false; AZ::Data::AssetInfo assetInfo; @@ -129,52 +129,72 @@ namespace ImageProcessingAtom { AZStd::string fullPath; AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath); - if (RenderThumbnailFromImage(thumbnailKey, thumbnailSize, IImageObjectPtr(LoadImageFromFile(fullPath)))) - { - return; - } + RenderThumbnailFromImage(thumbnailKey, thumbnailSize, + [fullPath]() { return IImageObjectPtr(LoadImageFromFile(fullPath)); } + ); } } - - auto productKey = azrtti_cast(thumbnailKey.data()); - if (productKey) + else if (auto productKey = azrtti_cast(thumbnailKey.data())) { - if (RenderThumbnailFromImage(thumbnailKey, thumbnailSize, Utils::LoadImageFromImageAsset(productKey->GetAssetId()))) - { - return; - } + RenderThumbnailFromImage(thumbnailKey, thumbnailSize, + [assetId = productKey->GetAssetId()]() { return Utils::LoadImageFromImageAsset(assetId); } + ); + } + else + { + AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event( + thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender); } - - AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event( - thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender); } - bool ImageThumbnailSystemComponent::RenderThumbnailFromImage( - AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize, IImageObjectPtr previewImage) const + template + void ImageThumbnailSystemComponent::RenderThumbnailFromImage( + AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize, MkImageFn mkPreviewImage) const { - if (!previewImage) + const auto JobRunner = [mkPreviewImage, thumbnailKey, thumbnailSize]() mutable { - return false; - } + IImageObjectPtr previewImage = mkPreviewImage(); + if (!previewImage) + { + AZ::SystemTickBus::QueueFunction( + [ + thumbnailKey + ]() + { + AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event( + thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender); + }); - ImageToProcess imageToProcess(previewImage); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - previewImage = imageToProcess.Get(); + return; + } - AZ::u8* imageBuf = nullptr; - AZ::u32 mip = 0; - AZ::u32 pitch = 0; - previewImage->GetImagePointer(mip, imageBuf, pitch); - const AZ::u32 width = previewImage->GetWidth(mip); - const AZ::u32 height = previewImage->GetHeight(mip); + ImageToProcess imageToProcess(previewImage); + imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); + previewImage = imageToProcess.Get(); - QImage image(imageBuf, width, height, pitch, QImage::Format_RGBA8888); + AZ::u8* imageBuf = nullptr; + AZ::u32 mip = 0; + AZ::u32 pitch = 0; + previewImage->GetImagePointer(mip, imageBuf, pitch); + const AZ::u32 width = previewImage->GetWidth(mip); + const AZ::u32 height = previewImage->GetHeight(mip); - AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event( - thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, - QPixmap::fromImage(image.scaled(QSize(thumbnailSize, thumbnailSize), Qt::KeepAspectRatio, Qt::SmoothTransformation))); + // Note that this image holds a non-owning pointer to the `previewImage' raw data buffer + const QImage image(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - return true; + // Dispatch event on main thread + AZ::SystemTickBus::QueueFunction( + [ + thumbnailKey, thumbnailSize, + pixmap = QPixmap::fromImage(image.scaled(QSize(thumbnailSize, thumbnailSize), Qt::KeepAspectRatio, Qt::SmoothTransformation)) + ]() mutable + { + AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event( + thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, + pixmap); + }); + }; + AZ::CreateJobFunction(JobRunner, true)->Start(); } } // namespace Thumbnails } // namespace ImageProcessingAtom diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.h index ca2453b532..e051b9e880 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnailSystemComponent.h @@ -52,8 +52,9 @@ namespace ImageProcessingAtom bool Installed() const override; void RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize) override; - bool RenderThumbnailFromImage( - AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize, IImageObjectPtr previewImage) const; + template + void RenderThumbnailFromImage( + AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize, MkImageFn mkPreviewImage) const; }; } // namespace Thumbnails } // namespace ImageProcessingAtom