mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 22:39:18 +02:00
Fix ImageReader threading issues
This commit is contained in:
parent
d899d7d696
commit
79e5286335
1 changed files with 37 additions and 21 deletions
|
@ -196,7 +196,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, const TextureLoaderFunc& texture
|
||||||
{
|
{
|
||||||
_textureLoader = textureLoader;
|
_textureLoader = textureLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case CUBE_TEXTURE: {
|
case CUBE_TEXTURE: {
|
||||||
|
@ -240,14 +240,14 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
||||||
class ImageReader : public QRunnable {
|
class ImageReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data, const QUrl& url = QUrl());
|
ImageReader(const QWeakPointer<Resource>& resource, const QByteArray& data, const QUrl& url = QUrl());
|
||||||
|
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void listSupportedImageFormats();
|
static void listSupportedImageFormats();
|
||||||
|
|
||||||
QWeakPointer<Resource> _texture;
|
QWeakPointer<Resource> _resource;
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
QByteArray _content;
|
QByteArray _content;
|
||||||
};
|
};
|
||||||
|
@ -261,9 +261,9 @@ void NetworkTexture::loadContent(const QByteArray& content) {
|
||||||
QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url));
|
QThreadPool::globalInstance()->start(new ImageReader(_self, content, _url));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageReader::ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data,
|
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QByteArray& data,
|
||||||
const QUrl& url) :
|
const QUrl& url) :
|
||||||
_texture(texture),
|
_resource(resource),
|
||||||
_url(url),
|
_url(url),
|
||||||
_content(data)
|
_content(data)
|
||||||
{
|
{
|
||||||
|
@ -284,25 +284,25 @@ void ImageReader::run() {
|
||||||
}
|
}
|
||||||
QThread::currentThread()->setPriority(QThread::LowPriority);
|
QThread::currentThread()->setPriority(QThread::LowPriority);
|
||||||
|
|
||||||
auto texture = _texture.toStrongRef();
|
if (!_resource.data()) {
|
||||||
if (!texture) {
|
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||||
qCWarning(modelnetworking) << "Could not get strong ref";
|
QThread::currentThread()->setPriority(originalPriority);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
listSupportedImageFormats();
|
listSupportedImageFormats();
|
||||||
|
|
||||||
// try to help the QImage loader by extracting the image file format from the url filename ext
|
// Help the QImage loader by extracting the image file format from the url filename ext.
|
||||||
// Some tga are not created properly for example without it
|
// Some tga are not created properly without it.
|
||||||
auto filename = _url.fileName().toStdString();
|
auto filename = _url.fileName().toStdString();
|
||||||
auto filenameExtension = filename.substr(filename.find_last_of('.') + 1);
|
auto filenameExtension = filename.substr(filename.find_last_of('.') + 1);
|
||||||
QImage image = QImage::fromData(_content, filenameExtension.c_str());
|
QImage image = QImage::fromData(_content, filenameExtension.c_str());
|
||||||
|
|
||||||
// Note that QImage.format is the pixel format which is different from the "format" of the image file...
|
// Note that QImage.format is the pixel format which is different from the "format" of the image file...
|
||||||
auto imageFormat = image.format();
|
auto imageFormat = image.format();
|
||||||
int originalWidth = image.width();
|
int originalWidth = image.width();
|
||||||
int originalHeight = image.height();
|
int originalHeight = image.height();
|
||||||
|
|
||||||
if (originalWidth == 0 || originalHeight == 0 || imageFormat == QImage::Format_Invalid) {
|
if (originalWidth == 0 || originalHeight == 0 || imageFormat == QImage::Format_Invalid) {
|
||||||
if (filenameExtension.empty()) {
|
if (filenameExtension.empty()) {
|
||||||
qCDebug(modelnetworking) << "QImage failed to create from content, no file extension:" << _url;
|
qCDebug(modelnetworking) << "QImage failed to create from content, no file extension:" << _url;
|
||||||
|
@ -312,15 +312,31 @@ void ImageReader::run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::Texture* theTexture = nullptr;
|
gpu::Texture* texture = nullptr;
|
||||||
auto ntex = texture.dynamicCast<NetworkTexture>();
|
{
|
||||||
if (ntex) {
|
// Double-check the resource still exists between long operations.
|
||||||
theTexture = ntex->getTextureLoader()(image, _url.toString().toStdString());
|
auto resource = _resource.toStrongRef();
|
||||||
|
if (!resource) {
|
||||||
|
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||||
|
QThread::currentThread()->setPriority(originalPriority);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto url = _url.toString().toStdString();
|
||||||
|
texture = resource.dynamicCast<NetworkTexture>()->getTextureLoader()(image, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the resource has not been deleted, and won't be while invokeMethod is in flight.
|
||||||
|
auto resource = _resource.toStrongRef();
|
||||||
|
if (!resource) {
|
||||||
|
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||||
|
delete texture;
|
||||||
|
} else {
|
||||||
|
QMetaObject::invokeMethod(resource.data(), "setImage", Qt::BlockingQueuedConnection,
|
||||||
|
Q_ARG(void*, texture),
|
||||||
|
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(texture.data(), "setImage",
|
|
||||||
Q_ARG(void*, theTexture),
|
|
||||||
Q_ARG(int, originalWidth), Q_ARG(int, originalHeight));
|
|
||||||
QThread::currentThread()->setPriority(originalPriority);
|
QThread::currentThread()->setPriority(originalPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,9 +344,9 @@ void NetworkTexture::setImage(void* voidTexture, int originalWidth,
|
||||||
int originalHeight) {
|
int originalHeight) {
|
||||||
_originalWidth = originalWidth;
|
_originalWidth = originalWidth;
|
||||||
_originalHeight = originalHeight;
|
_originalHeight = originalHeight;
|
||||||
|
|
||||||
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
gpu::Texture* texture = static_cast<gpu::Texture*>(voidTexture);
|
||||||
|
|
||||||
// Passing ownership
|
// Passing ownership
|
||||||
_textureSource->resetTexture(texture);
|
_textureSource->resetTexture(texture);
|
||||||
auto gpuTexture = _textureSource->getGPUTexture();
|
auto gpuTexture = _textureSource->getGPUTexture();
|
||||||
|
|
Loading…
Reference in a new issue