mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 01:31:37 +02:00
Merge pull request #7553 from zzmp/fix/tex-invoke-method
Fix ImageReader threading issues
This commit is contained in:
commit
ff4f693267
1 changed files with 46 additions and 28 deletions
|
@ -13,20 +13,22 @@
|
|||
|
||||
#include <mutex>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QPainter>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <qimagereader.h>
|
||||
#include <QImageReader>
|
||||
|
||||
#include <shared/NsightHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
|
||||
#include <shared/NsightHelpers.h>
|
||||
|
||||
#include <Finally.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "ModelNetworkingLogging.h"
|
||||
|
||||
TextureCache::TextureCache() {
|
||||
|
@ -242,14 +244,14 @@ NetworkTexture::TextureLoaderFunc NetworkTexture::getTextureLoader() const {
|
|||
class ImageReader : public QRunnable {
|
||||
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();
|
||||
|
||||
private:
|
||||
static void listSupportedImageFormats();
|
||||
|
||||
QWeakPointer<Resource> _texture;
|
||||
QWeakPointer<Resource> _resource;
|
||||
QUrl _url;
|
||||
QByteArray _content;
|
||||
};
|
||||
|
@ -263,9 +265,9 @@ void NetworkTexture::loadContent(const QByteArray& content) {
|
|||
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) :
|
||||
_texture(texture),
|
||||
_resource(resource),
|
||||
_url(url),
|
||||
_content(data)
|
||||
{
|
||||
|
@ -286,17 +288,19 @@ void ImageReader::run() {
|
|||
originalPriority = QThread::NormalPriority;
|
||||
}
|
||||
QThread::currentThread()->setPriority(QThread::LowPriority);
|
||||
Finally restorePriority([originalPriority]{
|
||||
QThread::currentThread()->setPriority(originalPriority);
|
||||
});
|
||||
|
||||
auto texture = _texture.toStrongRef();
|
||||
if (!texture) {
|
||||
qCWarning(modelnetworking) << "Could not get strong ref";
|
||||
if (!_resource.data()) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||
return;
|
||||
}
|
||||
|
||||
listSupportedImageFormats();
|
||||
|
||||
// try to 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
|
||||
// Help the QImage loader by extracting the image file format from the url filename ext.
|
||||
// Some tga are not created properly without it.
|
||||
auto filename = _url.fileName().toStdString();
|
||||
auto filenameExtension = filename.substr(filename.find_last_of('.') + 1);
|
||||
QImage image = QImage::fromData(_content, filenameExtension.c_str());
|
||||
|
@ -315,17 +319,31 @@ void ImageReader::run() {
|
|||
return;
|
||||
}
|
||||
|
||||
gpu::Texture* theTexture = nullptr;
|
||||
auto ntex = texture.dynamicCast<NetworkTexture>();
|
||||
if (ntex) {
|
||||
PROFILE_RANGE_EX(__FUNCTION__"::textureLoader", 0xffffff00, nullptr);
|
||||
theTexture = ntex->getTextureLoader()(image, _url.toString().toStdString());
|
||||
gpu::Texture* texture = nullptr;
|
||||
{
|
||||
// Double-check the resource still exists between long operations.
|
||||
auto resource = _resource.toStrongRef();
|
||||
if (!resource) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(texture.data(), "setImage",
|
||||
Q_ARG(void*, theTexture),
|
||||
auto url = _url.toString().toStdString();
|
||||
|
||||
PROFILE_RANGE_EX(__FUNCTION__"::textureLoader", 0xffffff00, nullptr);
|
||||
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));
|
||||
QThread::currentThread()->setPriority(originalPriority);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkTexture::setImage(void* voidTexture, int originalWidth,
|
||||
|
|
Loading…
Reference in a new issue