Merge pull request #1586 from yuriy0/DontBlockMainThreadToLoadTexturePreviews
Editor responsiveness: don't block main thread to load textures from disk
This commit is contained in:
@@ -51,6 +51,12 @@ namespace ImageProcessingAtom
|
|||||||
|
|
||||||
ImagePreviewer::~ImagePreviewer()
|
ImagePreviewer::~ImagePreviewer()
|
||||||
{
|
{
|
||||||
|
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||||
|
|
||||||
|
if (m_createDisplayTextureResult.isRunning())
|
||||||
|
{
|
||||||
|
m_createDisplayTextureResult.waitForFinished();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImagePreviewer::Clear() const
|
void ImagePreviewer::Clear() const
|
||||||
@@ -214,21 +220,30 @@ namespace ImageProcessingAtom
|
|||||||
m_ui->m_fileInfoCtrl->show();
|
m_ui->m_fileInfoCtrl->show();
|
||||||
m_fileinfo = QString::fromUtf8(product->GetName().c_str());
|
m_fileinfo = QString::fromUtf8(product->GetName().c_str());
|
||||||
m_fileinfo += GetFileSize(product->GetRelativePath().c_str());
|
m_fileinfo += GetFileSize(product->GetRelativePath().c_str());
|
||||||
|
|
||||||
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> imageAsset = Utils::LoadImageAsset(product->GetAssetId());
|
|
||||||
IImageObjectPtr image = Utils::LoadImageFromImageAsset(imageAsset);
|
|
||||||
|
|
||||||
if (image)
|
CreateAndDisplayTextureItemAsync(
|
||||||
|
[assetId = product->GetAssetId()]
|
||||||
|
() -> CreateDisplayTextureResult
|
||||||
{
|
{
|
||||||
// Add product image info
|
AZ::Data::Asset<AZ::RPI::StreamingImageAsset> imageAsset = Utils::LoadImageAsset(assetId);
|
||||||
AZStd::string productInfo;
|
IImageObjectPtr image = Utils::LoadImageFromImageAsset(imageAsset);
|
||||||
GetImageInfoString(imageAsset, productInfo);
|
|
||||||
|
|
||||||
m_fileinfo += QStringLiteral("\r\n");
|
if (image)
|
||||||
m_fileinfo += productInfo.c_str();
|
{
|
||||||
|
// Add product image info
|
||||||
|
AZStd::string productInfo;
|
||||||
|
GetImageInfoString(imageAsset, productInfo);
|
||||||
|
|
||||||
m_previewImageObject = ConvertImageForPreview(image);
|
QString fileInfo = QStringLiteral("\r\n");
|
||||||
}
|
fileInfo += productInfo.c_str();
|
||||||
|
|
||||||
|
return { ConvertImageForPreview(image), fileInfo };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { nullptr, "" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
DisplayTextureItem();
|
DisplayTextureItem();
|
||||||
}
|
}
|
||||||
@@ -239,19 +254,28 @@ namespace ImageProcessingAtom
|
|||||||
m_fileinfo = QString::fromUtf8(source->GetName().c_str());
|
m_fileinfo = QString::fromUtf8(source->GetName().c_str());
|
||||||
m_fileinfo += GetFileSize(source->GetFullPath().c_str());
|
m_fileinfo += GetFileSize(source->GetFullPath().c_str());
|
||||||
|
|
||||||
IImageObjectPtr image = IImageObjectPtr(LoadImageFromFile(source->GetFullPath()));
|
CreateAndDisplayTextureItemAsync(
|
||||||
|
[fullPath = source->GetFullPath()]
|
||||||
if (image)
|
() -> CreateDisplayTextureResult
|
||||||
{
|
{
|
||||||
// Add source image info
|
IImageObjectPtr image = IImageObjectPtr(LoadImageFromFile(fullPath));
|
||||||
AZStd::string sourceInfo;
|
|
||||||
GetImageInfoString(image, sourceInfo);
|
|
||||||
|
|
||||||
m_fileinfo += QStringLiteral("\r\n");
|
if (image)
|
||||||
m_fileinfo += sourceInfo.c_str();
|
{
|
||||||
|
// Add source image info
|
||||||
|
AZStd::string sourceInfo;
|
||||||
|
GetImageInfoString(image, sourceInfo);
|
||||||
|
|
||||||
m_previewImageObject = ConvertImageForPreview(image);
|
QString fileInfo = QStringLiteral("\r\n");
|
||||||
}
|
fileInfo += sourceInfo.c_str();
|
||||||
|
|
||||||
|
return { ConvertImageForPreview(image), fileInfo };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return { nullptr, "" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
DisplayTextureItem();
|
DisplayTextureItem();
|
||||||
}
|
}
|
||||||
@@ -289,6 +313,27 @@ namespace ImageProcessingAtom
|
|||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class CreateFn>
|
||||||
|
void ImagePreviewer::CreateAndDisplayTextureItemAsync(CreateFn create)
|
||||||
|
{
|
||||||
|
AZ::SystemTickBus::Handler::BusConnect();
|
||||||
|
m_createDisplayTextureResult = QtConcurrent::run(AZStd::move(create));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagePreviewer::OnSystemTick()
|
||||||
|
{
|
||||||
|
if (m_createDisplayTextureResult.isFinished())
|
||||||
|
{
|
||||||
|
CreateDisplayTextureResult result = m_createDisplayTextureResult.result();
|
||||||
|
m_previewImageObject = AZStd::move(result.first);
|
||||||
|
m_fileinfo += result.second;
|
||||||
|
|
||||||
|
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||||
|
|
||||||
|
DisplayTextureItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImagePreviewer::PreviewSubImage(uint32_t mip)
|
void ImagePreviewer::PreviewSubImage(uint32_t mip)
|
||||||
{
|
{
|
||||||
QImage previewImage = GetSubImagePreview(m_previewImageObject, mip);
|
QImage previewImage = GetSubImagePreview(m_previewImageObject, mip);
|
||||||
|
|||||||
@@ -13,12 +13,15 @@
|
|||||||
|
|
||||||
#if !defined(Q_MOC_RUN)
|
#if !defined(Q_MOC_RUN)
|
||||||
#include <AzCore/Memory/SystemAllocator.h>
|
#include <AzCore/Memory/SystemAllocator.h>
|
||||||
|
#include <AzCore/Component/TickBus.h>
|
||||||
#include <AzToolsFramework/AssetBrowser/Previewer/Previewer.h>
|
#include <AzToolsFramework/AssetBrowser/Previewer/Previewer.h>
|
||||||
|
|
||||||
#include <Atom/ImageProcessing/ImageObject.h>
|
#include <Atom/ImageProcessing/ImageObject.h>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
@@ -42,6 +45,7 @@ namespace ImageProcessingAtom
|
|||||||
{
|
{
|
||||||
class ImagePreviewer
|
class ImagePreviewer
|
||||||
: public AzToolsFramework::AssetBrowser::Previewer
|
: public AzToolsFramework::AssetBrowser::Previewer
|
||||||
|
, private AZ::SystemTickBus::Handler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -65,16 +69,27 @@ namespace ImageProcessingAtom
|
|||||||
QString GetFileSize(const char* path);
|
QString GetFileSize(const char* path);
|
||||||
|
|
||||||
void DisplayTextureItem();
|
void DisplayTextureItem();
|
||||||
|
template<class CreateFn>
|
||||||
|
void CreateAndDisplayTextureItemAsync(CreateFn create);
|
||||||
|
|
||||||
void PreviewSubImage(uint32_t mip);
|
void PreviewSubImage(uint32_t mip);
|
||||||
|
|
||||||
// QLabel word wrap does not break long words such as filenames, so manual word wrap needed
|
// QLabel word wrap does not break long words such as filenames, so manual word wrap needed
|
||||||
static QString WordWrap(const QString& string, int maxLength);
|
static QString WordWrap(const QString& string, int maxLength);
|
||||||
|
|
||||||
|
// SystemTickBus
|
||||||
|
void OnSystemTick() override;
|
||||||
|
|
||||||
QScopedPointer<Ui::ImagePreviewerClass> m_ui;
|
QScopedPointer<Ui::ImagePreviewerClass> m_ui;
|
||||||
QString m_fileinfo;
|
QString m_fileinfo;
|
||||||
QString m_name = "ImagePreviewer";
|
QString m_name = "ImagePreviewer";
|
||||||
|
|
||||||
// Decompressed image in preview. Cache it so we can preview its sub images
|
// Decompressed image in preview. Cache it so we can preview its sub images
|
||||||
IImageObjectPtr m_previewImageObject;
|
IImageObjectPtr m_previewImageObject;
|
||||||
|
|
||||||
|
// Properties for tracking the status of an asynchronous request to display an asset browser entry
|
||||||
|
using CreateDisplayTextureResult = AZStd::pair<IImageObjectPtr, QString>;
|
||||||
|
|
||||||
|
QFuture<CreateDisplayTextureResult> m_createDisplayTextureResult;
|
||||||
};
|
};
|
||||||
}//namespace ImageProcessingAtom
|
}//namespace ImageProcessingAtom
|
||||||
|
|||||||
Reference in New Issue
Block a user