diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9a3e2bde87..a5212ac580 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -277,6 +277,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _networkAccessManager->setCache(cache); ResourceCache::setNetworkAccessManager(_networkAccessManager); + ResourceCache::setRequestLimit(3); _window->setCentralWidget(_glWidget); diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index e391e7414b..e9719e7a84 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -290,7 +290,7 @@ QSharedPointer GeometryCache::getGeometry(const QUrl& url, cons } QSharedPointer GeometryCache::createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra) { + const QSharedPointer& fallback, bool delayLoad, const void* extra) { QSharedPointer geometry(new NetworkGeometry(url, fallback.staticCast(), delayLoad)); geometry->setLODParent(geometry); @@ -377,6 +377,57 @@ glm::vec4 NetworkGeometry::computeAverageColor() const { return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / totalTriangles; } +void NetworkGeometry::setLoadPriority(const QPointer& owner, float priority) { + Resource::setLoadPriority(owner, priority); + + for (int i = 0; i < _meshes.size(); i++) { + NetworkMesh& mesh = _meshes[i]; + for (int j = 0; j < mesh.parts.size(); j++) { + NetworkMeshPart& part = mesh.parts[j]; + if (part.diffuseTexture) { + part.diffuseTexture->setLoadPriority(owner, priority); + } + if (part.normalTexture) { + part.normalTexture->setLoadPriority(owner, priority); + } + } + } +} + +void NetworkGeometry::setLoadPriorities(const QHash, float>& priorities) { + Resource::setLoadPriorities(priorities); + + for (int i = 0; i < _meshes.size(); i++) { + NetworkMesh& mesh = _meshes[i]; + for (int j = 0; j < mesh.parts.size(); j++) { + NetworkMeshPart& part = mesh.parts[j]; + if (part.diffuseTexture) { + part.diffuseTexture->setLoadPriorities(priorities); + } + if (part.normalTexture) { + part.normalTexture->setLoadPriorities(priorities); + } + } + } +} + +void NetworkGeometry::clearLoadPriority(const QPointer& owner) { + Resource::clearLoadPriority(owner); + + for (int i = 0; i < _meshes.size(); i++) { + NetworkMesh& mesh = _meshes[i]; + for (int j = 0; j < mesh.parts.size(); j++) { + NetworkMeshPart& part = mesh.parts[j]; + if (part.diffuseTexture) { + part.diffuseTexture->clearLoadPriority(owner); + } + if (part.normalTexture) { + part.normalTexture->clearLoadPriority(owner); + } + } + } +} + void NetworkGeometry::downloadFinished(QNetworkReply* reply) { QUrl url = reply->url(); QByteArray data = reply->readAll(); @@ -433,10 +484,12 @@ void NetworkGeometry::downloadFinished(QNetworkReply* reply) { if (!part.diffuseFilename.isEmpty()) { networkPart.diffuseTexture = Application::getInstance()->getTextureCache()->getTexture( _textureBase.resolved(QUrl(part.diffuseFilename)), false, mesh.isEye); + networkPart.diffuseTexture->setLoadPriorities(_loadPriorities); } if (!part.normalFilename.isEmpty()) { networkPart.normalTexture = Application::getInstance()->getTextureCache()->getTexture( _textureBase.resolved(QUrl(part.normalFilename)), true); + networkPart.normalTexture->setLoadPriorities(_loadPriorities); } networkMesh.parts.append(networkPart); diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index bdd050d892..e5139088d3 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -42,7 +42,7 @@ public: protected: virtual QSharedPointer createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra); + const QSharedPointer& fallback, bool delayLoad, const void* extra); private: @@ -82,6 +82,10 @@ public: /// Returns the average color of all meshes in the geometry. glm::vec4 computeAverageColor() const; + virtual void setLoadPriority(const QPointer& owner, float priority); + virtual void setLoadPriorities(const QHash, float>& priorities); + virtual void clearLoadPriority(const QPointer& owner); + protected: virtual void downloadFinished(QNetworkReply* reply); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 55594fa3dc..599abf29aa 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -139,6 +139,7 @@ void Model::simulate(float deltaTime, bool delayLoad) { _geometry = geometry; } if (!delayLoad) { + _geometry->setLoadPriority(this, -_lodDistance); _geometry->ensureLoading(); } } @@ -833,6 +834,10 @@ void Model::deleteGeometry() { _blendedVertexBufferIDs.clear(); _jointStates.clear(); _meshStates.clear(); + + if (_geometry) { + _geometry->clearLoadPriority(this); + } } void Model::renderMeshes(float alpha, bool translucent) { diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 69eef755c1..0a6a3fe6f8 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -122,15 +122,16 @@ GLuint TextureCache::getFileTextureID(const QString& filename) { return id; } -class TextureExtra { -public: - bool normalMap; - bool dilatable; -}; - QSharedPointer TextureCache::getTexture(const QUrl& url, bool normalMap, bool dilatable) { - TextureExtra extra = { normalMap, dilatable }; - return getResource(url, QUrl(), false, &extra).staticCast(); + if (!dilatable) { + return ResourceCache::getResource(url, QUrl(), false, &normalMap).staticCast(); + } + QSharedPointer texture = _dilatableNetworkTextures.value(url); + if (texture.isNull()) { + texture = QSharedPointer(new DilatableNetworkTexture(url)); + _dilatableNetworkTextures.insert(url, texture); + } + return texture; } QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() { @@ -226,10 +227,8 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) { } QSharedPointer TextureCache::createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra) { - TextureExtra* textureExtra = static_cast(extra); - return QSharedPointer(textureExtra->dilatable ? new DilatableNetworkTexture(url, textureExtra->normalMap) : - new NetworkTexture(url, textureExtra->normalMap)); + const QSharedPointer& fallback, bool delayLoad, const void* extra) { + return QSharedPointer(new NetworkTexture(url, *(const bool*)extra)); } QOpenGLFramebufferObject* TextureCache::createFramebufferObject() { @@ -311,8 +310,8 @@ void NetworkTexture::imageLoaded(const QImage& image) { // nothing by default } -DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, bool normalMap) : - NetworkTexture(url, normalMap), +DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url) : + NetworkTexture(url, false), _innerRadius(0), _outerRadius(0) { diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index b735ef58cd..2c8f4d7cf9 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -72,7 +72,7 @@ public: protected: virtual QSharedPointer createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra); + const QSharedPointer& fallback, bool delayLoad, const void* extra); private: @@ -144,7 +144,7 @@ class DilatableNetworkTexture : public NetworkTexture { public: - DilatableNetworkTexture(const QUrl& url, bool normalMap); + DilatableNetworkTexture(const QUrl& url); /// Returns a pointer to a texture with the requested amount of dilation. QSharedPointer getDilatedTexture(float dilation); diff --git a/libraries/metavoxels/src/ScriptCache.cpp b/libraries/metavoxels/src/ScriptCache.cpp index ffa429a36f..da29186541 100644 --- a/libraries/metavoxels/src/ScriptCache.cpp +++ b/libraries/metavoxels/src/ScriptCache.cpp @@ -50,7 +50,7 @@ QSharedPointer ScriptCache::getValue(const ParameterizedURL& url) } QSharedPointer ScriptCache::createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra) { + const QSharedPointer& fallback, bool delayLoad, const void* extra) { return QSharedPointer(new NetworkProgram(this, url)); } diff --git a/libraries/metavoxels/src/ScriptCache.h b/libraries/metavoxels/src/ScriptCache.h index 20905ecc5f..072020d882 100644 --- a/libraries/metavoxels/src/ScriptCache.h +++ b/libraries/metavoxels/src/ScriptCache.h @@ -49,7 +49,7 @@ public: protected: virtual QSharedPointer createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra); + const QSharedPointer& fallback, bool delayLoad, const void* extra); private: diff --git a/libraries/shared/src/ResourceCache.cpp b/libraries/shared/src/ResourceCache.cpp index 100e1b9469..24350794bc 100644 --- a/libraries/shared/src/ResourceCache.cpp +++ b/libraries/shared/src/ResourceCache.cpp @@ -105,6 +105,21 @@ void Resource::ensureLoading() { } } +void Resource::setLoadPriority(const QPointer& owner, float priority) { + _loadPriorities.insert(owner, priority); +} + +void Resource::setLoadPriorities(const QHash, float>& priorities) { + for (QHash, float>::const_iterator it = priorities.constBegin(); + it != priorities.constEnd(); it++) { + _loadPriorities.insert(it.key(), it.value()); + } +} + +void Resource::clearLoadPriority(const QPointer& owner) { + _loadPriorities.remove(owner); +} + float Resource::getLoadPriority() { float highestPriority = -FLT_MAX; for (QHash, float>::iterator it = _loadPriorities.begin(); it != _loadPriorities.end(); ) { diff --git a/libraries/shared/src/ResourceCache.h b/libraries/shared/src/ResourceCache.h index 571d76b844..ac8ef68a05 100644 --- a/libraries/shared/src/ResourceCache.h +++ b/libraries/shared/src/ResourceCache.h @@ -48,7 +48,7 @@ protected: /// Creates a new resource. virtual QSharedPointer createResource(const QUrl& url, - const QSharedPointer& fallback, bool delayLoad, void* extra) = 0; + const QSharedPointer& fallback, bool delayLoad, const void* extra) = 0; static void attemptRequest(Resource* resource); static void requestCompleted(); @@ -77,10 +77,13 @@ public: void ensureLoading(); /// Sets the load priority for one owner. - void setLoadPriority(const QPointer& owner, float priority) { _loadPriorities.insert(owner, priority); } + virtual void setLoadPriority(const QPointer& owner, float priority); + + /// Sets a set of priorities at once. + virtual void setLoadPriorities(const QHash, float>& priorities); /// Clears the load priority for one owner. - void clearLoadPriority(const QPointer& owner) { _loadPriorities.remove(owner); } + virtual void clearLoadPriority(const QPointer& owner); /// Returns the highest load priority across all owners. float getLoadPriority(); @@ -96,6 +99,7 @@ protected: QNetworkRequest _request; bool _startedLoading; bool _failedToLoad; + QHash, float> _loadPriorities; private slots: @@ -110,8 +114,6 @@ private: QNetworkReply* _reply; int _attempts; - - QHash, float> _loadPriorities; }; uint qHash(const QPointer& value, uint seed = 0);