Do the actual reading of the reply on the worker thread. Otherwise, when we

read from the cache, we're reading synchronously from a file.  Closes #2171.
This commit is contained in:
Andrzej Kapolka 2014-03-03 15:16:13 -08:00
parent 9759cd70c0
commit 7ecfeeaba3
5 changed files with 20 additions and 16 deletions

View file

@ -450,7 +450,7 @@ class GeometryReader : public QRunnable {
public: public:
GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url, GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
const QByteArray& data, const QVariantHash& mapping); QNetworkReply* reply, const QVariantHash& mapping);
virtual void run(); virtual void run();
@ -458,40 +458,41 @@ private:
QWeakPointer<Resource> _geometry; QWeakPointer<Resource> _geometry;
QUrl _url; QUrl _url;
QByteArray _data; QNetworkReply* _reply;
QVariantHash _mapping; QVariantHash _mapping;
}; };
GeometryReader::GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url, GeometryReader::GeometryReader(const QWeakPointer<Resource>& geometry, const QUrl& url,
const QByteArray& data, const QVariantHash& mapping) : QNetworkReply* reply, const QVariantHash& mapping) :
_geometry(geometry), _geometry(geometry),
_url(url), _url(url),
_data(data), _reply(reply),
_mapping(mapping) { _mapping(mapping) {
} }
void GeometryReader::run() { void GeometryReader::run() {
QSharedPointer<Resource> geometry = _geometry.toStrongRef(); QSharedPointer<Resource> geometry = _geometry.toStrongRef();
if (geometry.isNull()) { if (geometry.isNull()) {
_reply->deleteLater();
return; return;
} }
try { try {
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&,
_url.path().toLower().endsWith(".svo") ? readSVO(_data) : readFBX(_data, _mapping))); _url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping)));
} catch (const QString& error) { } catch (const QString& error) {
qDebug() << "Error reading " << _url << ": " << error; qDebug() << "Error reading " << _url << ": " << error;
QMetaObject::invokeMethod(geometry.data(), "finishedLoading", Q_ARG(bool, false)); QMetaObject::invokeMethod(geometry.data(), "finishedLoading", Q_ARG(bool, false));
} }
_reply->deleteLater();
} }
void NetworkGeometry::downloadFinished(QNetworkReply* reply) { void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
QUrl url = reply->url(); QUrl url = reply->url();
QByteArray data = reply->readAll();
if (url.path().toLower().endsWith(".fst")) { if (url.path().toLower().endsWith(".fst")) {
// it's a mapping file; parse it and get the mesh filename // it's a mapping file; parse it and get the mesh filename
_mapping = readMapping(data); _mapping = readMapping(reply->readAll());
reply->deleteLater();
QString filename = _mapping.value("filename").toString(); QString filename = _mapping.value("filename").toString();
if (filename.isNull()) { if (filename.isNull()) {
qDebug() << "Mapping file " << url << " has no filename."; qDebug() << "Mapping file " << url << " has no filename.";
@ -525,7 +526,7 @@ void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
} }
// send the reader off to the thread pool // send the reader off to the thread pool
QThreadPool::globalInstance()->start(new GeometryReader(_self, url, data, _mapping)); QThreadPool::globalInstance()->start(new GeometryReader(_self, url, reply, _mapping));
} }
void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { void NetworkGeometry::setGeometry(const FBXGeometry& geometry) {

View file

@ -273,27 +273,28 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) :
class ImageReader : public QRunnable { class ImageReader : public QRunnable {
public: public:
ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data); ImageReader(const QWeakPointer<Resource>& texture, QNetworkReply* reply);
virtual void run(); virtual void run();
private: private:
QWeakPointer<Resource> _texture; QWeakPointer<Resource> _texture;
QByteArray _data; QNetworkReply* _reply;
}; };
ImageReader::ImageReader(const QWeakPointer<Resource>& texture, const QByteArray& data) : ImageReader::ImageReader(const QWeakPointer<Resource>& texture, QNetworkReply* reply) :
_texture(texture), _texture(texture),
_data(data) { _reply(reply) {
} }
void ImageReader::run() { void ImageReader::run() {
QSharedPointer<Resource> texture = _texture.toStrongRef(); QSharedPointer<Resource> texture = _texture.toStrongRef();
if (texture.isNull()) { if (texture.isNull()) {
_reply->deleteLater();
return; return;
} }
QImage image = QImage::fromData(_data); QImage image = QImage::fromData(_reply->readAll());
if (image.format() != QImage::Format_ARGB32) { if (image.format() != QImage::Format_ARGB32) {
image = image.convertToFormat(QImage::Format_ARGB32); image = image.convertToFormat(QImage::Format_ARGB32);
} }
@ -320,11 +321,12 @@ void ImageReader::run() {
QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image), QMetaObject::invokeMethod(texture.data(), "setImage", Q_ARG(const QImage&, image),
Q_ARG(const glm::vec4&, accumulated / (imageArea * EIGHT_BIT_MAXIMUM)), Q_ARG(const glm::vec4&, accumulated / (imageArea * EIGHT_BIT_MAXIMUM)),
Q_ARG(bool, translucentPixels >= imageArea / 2)); Q_ARG(bool, translucentPixels >= imageArea / 2));
_reply->deleteLater();
} }
void NetworkTexture::downloadFinished(QNetworkReply* reply) { void NetworkTexture::downloadFinished(QNetworkReply* reply) {
// send the reader off to the thread pool // send the reader off to the thread pool
QThreadPool::globalInstance()->start(new ImageReader(_self, reply->readAll())); QThreadPool::globalInstance()->start(new ImageReader(_self, reply));
} }
void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor, bool translucent) { void NetworkTexture::setImage(const QImage& image, const glm::vec4& averageColor, bool translucent) {

View file

@ -61,6 +61,7 @@ NetworkProgram::NetworkProgram(ScriptCache* cache, const QUrl& url) :
void NetworkProgram::downloadFinished(QNetworkReply* reply) { void NetworkProgram::downloadFinished(QNetworkReply* reply) {
_program = QScriptProgram(QTextStream(reply).readAll(), reply->url().toString()); _program = QScriptProgram(QTextStream(reply).readAll(), reply->url().toString());
reply->deleteLater();
finishedLoading(true); finishedLoading(true);
emit loaded(); emit loaded();
} }

View file

@ -161,7 +161,6 @@ void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
return; return;
} }
_reply->disconnect(this); _reply->disconnect(this);
_reply->deleteLater();
QNetworkReply* reply = _reply; QNetworkReply* reply = _reply;
_reply = NULL; _reply = NULL;
ResourceCache::requestCompleted(); ResourceCache::requestCompleted();

View file

@ -99,6 +99,7 @@ protected slots:
protected: protected:
/// Called when the download has finished. The recipient should delete the reply when done with it.
virtual void downloadFinished(QNetworkReply* reply) = 0; virtual void downloadFinished(QNetworkReply* reply) = 0;
/// Should be called by subclasses when all the loading that will be done has been done. /// Should be called by subclasses when all the loading that will be done has been done.