Further work on request limiting.

This commit is contained in:
Andrzej Kapolka 2014-02-27 19:28:45 -08:00
parent 5d4ed4c85e
commit 73ec568b4b
10 changed files with 104 additions and 25 deletions

View file

@ -277,6 +277,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_networkAccessManager->setCache(cache); _networkAccessManager->setCache(cache);
ResourceCache::setNetworkAccessManager(_networkAccessManager); ResourceCache::setNetworkAccessManager(_networkAccessManager);
ResourceCache::setRequestLimit(3);
_window->setCentralWidget(_glWidget); _window->setCentralWidget(_glWidget);

View file

@ -290,7 +290,7 @@ QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, cons
} }
QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url, QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra) { const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
QSharedPointer<NetworkGeometry> geometry(new NetworkGeometry(url, fallback.staticCast<NetworkGeometry>(), delayLoad)); QSharedPointer<NetworkGeometry> geometry(new NetworkGeometry(url, fallback.staticCast<NetworkGeometry>(), delayLoad));
geometry->setLODParent(geometry); 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; return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / totalTriangles;
} }
void NetworkGeometry::setLoadPriority(const QPointer<QObject>& 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<QPointer<QObject>, 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<QObject>& 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) { void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
QUrl url = reply->url(); QUrl url = reply->url();
QByteArray data = reply->readAll(); QByteArray data = reply->readAll();
@ -433,10 +484,12 @@ void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
if (!part.diffuseFilename.isEmpty()) { if (!part.diffuseFilename.isEmpty()) {
networkPart.diffuseTexture = Application::getInstance()->getTextureCache()->getTexture( networkPart.diffuseTexture = Application::getInstance()->getTextureCache()->getTexture(
_textureBase.resolved(QUrl(part.diffuseFilename)), false, mesh.isEye); _textureBase.resolved(QUrl(part.diffuseFilename)), false, mesh.isEye);
networkPart.diffuseTexture->setLoadPriorities(_loadPriorities);
} }
if (!part.normalFilename.isEmpty()) { if (!part.normalFilename.isEmpty()) {
networkPart.normalTexture = Application::getInstance()->getTextureCache()->getTexture( networkPart.normalTexture = Application::getInstance()->getTextureCache()->getTexture(
_textureBase.resolved(QUrl(part.normalFilename)), true); _textureBase.resolved(QUrl(part.normalFilename)), true);
networkPart.normalTexture->setLoadPriorities(_loadPriorities);
} }
networkMesh.parts.append(networkPart); networkMesh.parts.append(networkPart);

View file

@ -42,7 +42,7 @@ public:
protected: protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url, virtual QSharedPointer<Resource> createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra); const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
private: private:
@ -82,6 +82,10 @@ public:
/// Returns the average color of all meshes in the geometry. /// Returns the average color of all meshes in the geometry.
glm::vec4 computeAverageColor() const; glm::vec4 computeAverageColor() const;
virtual void setLoadPriority(const QPointer<QObject>& owner, float priority);
virtual void setLoadPriorities(const QHash<QPointer<QObject>, float>& priorities);
virtual void clearLoadPriority(const QPointer<QObject>& owner);
protected: protected:
virtual void downloadFinished(QNetworkReply* reply); virtual void downloadFinished(QNetworkReply* reply);

View file

@ -139,6 +139,7 @@ void Model::simulate(float deltaTime, bool delayLoad) {
_geometry = geometry; _geometry = geometry;
} }
if (!delayLoad) { if (!delayLoad) {
_geometry->setLoadPriority(this, -_lodDistance);
_geometry->ensureLoading(); _geometry->ensureLoading();
} }
} }
@ -833,6 +834,10 @@ void Model::deleteGeometry() {
_blendedVertexBufferIDs.clear(); _blendedVertexBufferIDs.clear();
_jointStates.clear(); _jointStates.clear();
_meshStates.clear(); _meshStates.clear();
if (_geometry) {
_geometry->clearLoadPriority(this);
}
} }
void Model::renderMeshes(float alpha, bool translucent) { void Model::renderMeshes(float alpha, bool translucent) {

View file

@ -122,15 +122,16 @@ GLuint TextureCache::getFileTextureID(const QString& filename) {
return id; return id;
} }
class TextureExtra {
public:
bool normalMap;
bool dilatable;
};
QSharedPointer<NetworkTexture> TextureCache::getTexture(const QUrl& url, bool normalMap, bool dilatable) { QSharedPointer<NetworkTexture> TextureCache::getTexture(const QUrl& url, bool normalMap, bool dilatable) {
TextureExtra extra = { normalMap, dilatable }; if (!dilatable) {
return getResource(url, QUrl(), false, &extra).staticCast<NetworkTexture>(); return ResourceCache::getResource(url, QUrl(), false, &normalMap).staticCast<NetworkTexture>();
}
QSharedPointer<NetworkTexture> texture = _dilatableNetworkTextures.value(url);
if (texture.isNull()) {
texture = QSharedPointer<NetworkTexture>(new DilatableNetworkTexture(url));
_dilatableNetworkTextures.insert(url, texture);
}
return texture;
} }
QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() { QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
@ -226,10 +227,8 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
} }
QSharedPointer<Resource> TextureCache::createResource(const QUrl& url, QSharedPointer<Resource> TextureCache::createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra) { const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
TextureExtra* textureExtra = static_cast<TextureExtra*>(extra); return QSharedPointer<Resource>(new NetworkTexture(url, *(const bool*)extra));
return QSharedPointer<Resource>(textureExtra->dilatable ? new DilatableNetworkTexture(url, textureExtra->normalMap) :
new NetworkTexture(url, textureExtra->normalMap));
} }
QOpenGLFramebufferObject* TextureCache::createFramebufferObject() { QOpenGLFramebufferObject* TextureCache::createFramebufferObject() {
@ -311,8 +310,8 @@ void NetworkTexture::imageLoaded(const QImage& image) {
// nothing by default // nothing by default
} }
DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, bool normalMap) : DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url) :
NetworkTexture(url, normalMap), NetworkTexture(url, false),
_innerRadius(0), _innerRadius(0),
_outerRadius(0) _outerRadius(0)
{ {

View file

@ -72,7 +72,7 @@ public:
protected: protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url, virtual QSharedPointer<Resource> createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra); const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
private: private:
@ -144,7 +144,7 @@ class DilatableNetworkTexture : public NetworkTexture {
public: public:
DilatableNetworkTexture(const QUrl& url, bool normalMap); DilatableNetworkTexture(const QUrl& url);
/// Returns a pointer to a texture with the requested amount of dilation. /// Returns a pointer to a texture with the requested amount of dilation.
QSharedPointer<Texture> getDilatedTexture(float dilation); QSharedPointer<Texture> getDilatedTexture(float dilation);

View file

@ -50,7 +50,7 @@ QSharedPointer<NetworkValue> ScriptCache::getValue(const ParameterizedURL& url)
} }
QSharedPointer<Resource> ScriptCache::createResource(const QUrl& url, QSharedPointer<Resource> ScriptCache::createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra) { const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
return QSharedPointer<Resource>(new NetworkProgram(this, url)); return QSharedPointer<Resource>(new NetworkProgram(this, url));
} }

View file

@ -49,7 +49,7 @@ public:
protected: protected:
virtual QSharedPointer<Resource> createResource(const QUrl& url, virtual QSharedPointer<Resource> createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra); const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra);
private: private:

View file

@ -105,6 +105,21 @@ void Resource::ensureLoading() {
} }
} }
void Resource::setLoadPriority(const QPointer<QObject>& owner, float priority) {
_loadPriorities.insert(owner, priority);
}
void Resource::setLoadPriorities(const QHash<QPointer<QObject>, float>& priorities) {
for (QHash<QPointer<QObject>, float>::const_iterator it = priorities.constBegin();
it != priorities.constEnd(); it++) {
_loadPriorities.insert(it.key(), it.value());
}
}
void Resource::clearLoadPriority(const QPointer<QObject>& owner) {
_loadPriorities.remove(owner);
}
float Resource::getLoadPriority() { float Resource::getLoadPriority() {
float highestPriority = -FLT_MAX; float highestPriority = -FLT_MAX;
for (QHash<QPointer<QObject>, float>::iterator it = _loadPriorities.begin(); it != _loadPriorities.end(); ) { for (QHash<QPointer<QObject>, float>::iterator it = _loadPriorities.begin(); it != _loadPriorities.end(); ) {

View file

@ -48,7 +48,7 @@ protected:
/// Creates a new resource. /// Creates a new resource.
virtual QSharedPointer<Resource> createResource(const QUrl& url, virtual QSharedPointer<Resource> createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra) = 0; const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) = 0;
static void attemptRequest(Resource* resource); static void attemptRequest(Resource* resource);
static void requestCompleted(); static void requestCompleted();
@ -77,10 +77,13 @@ public:
void ensureLoading(); void ensureLoading();
/// Sets the load priority for one owner. /// Sets the load priority for one owner.
void setLoadPriority(const QPointer<QObject>& owner, float priority) { _loadPriorities.insert(owner, priority); } virtual void setLoadPriority(const QPointer<QObject>& owner, float priority);
/// Sets a set of priorities at once.
virtual void setLoadPriorities(const QHash<QPointer<QObject>, float>& priorities);
/// Clears the load priority for one owner. /// Clears the load priority for one owner.
void clearLoadPriority(const QPointer<QObject>& owner) { _loadPriorities.remove(owner); } virtual void clearLoadPriority(const QPointer<QObject>& owner);
/// Returns the highest load priority across all owners. /// Returns the highest load priority across all owners.
float getLoadPriority(); float getLoadPriority();
@ -96,6 +99,7 @@ protected:
QNetworkRequest _request; QNetworkRequest _request;
bool _startedLoading; bool _startedLoading;
bool _failedToLoad; bool _failedToLoad;
QHash<QPointer<QObject>, float> _loadPriorities;
private slots: private slots:
@ -110,8 +114,6 @@ private:
QNetworkReply* _reply; QNetworkReply* _reply;
int _attempts; int _attempts;
QHash<QPointer<QObject>, float> _loadPriorities;
}; };
uint qHash(const QPointer<QObject>& value, uint seed = 0); uint qHash(const QPointer<QObject>& value, uint seed = 0);