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);
ResourceCache::setNetworkAccessManager(_networkAccessManager);
ResourceCache::setRequestLimit(3);
_window->setCentralWidget(_glWidget);

View file

@ -290,7 +290,7 @@ QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, cons
}
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));
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<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) {
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);

View file

@ -42,7 +42,7 @@ public:
protected:
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:
@ -82,6 +82,10 @@ public:
/// Returns the average color of all meshes in the geometry.
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:
virtual void downloadFinished(QNetworkReply* reply);

View file

@ -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) {

View file

@ -122,15 +122,16 @@ GLuint TextureCache::getFileTextureID(const QString& filename) {
return id;
}
class TextureExtra {
public:
bool normalMap;
bool dilatable;
};
QSharedPointer<NetworkTexture> TextureCache::getTexture(const QUrl& url, bool normalMap, bool dilatable) {
TextureExtra extra = { normalMap, dilatable };
return getResource(url, QUrl(), false, &extra).staticCast<NetworkTexture>();
if (!dilatable) {
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() {
@ -226,10 +227,8 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
}
QSharedPointer<Resource> TextureCache::createResource(const QUrl& url,
const QSharedPointer<Resource>& fallback, bool delayLoad, void* extra) {
TextureExtra* textureExtra = static_cast<TextureExtra*>(extra);
return QSharedPointer<Resource>(textureExtra->dilatable ? new DilatableNetworkTexture(url, textureExtra->normalMap) :
new NetworkTexture(url, textureExtra->normalMap));
const QSharedPointer<Resource>& fallback, bool delayLoad, const void* extra) {
return QSharedPointer<Resource>(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)
{

View file

@ -72,7 +72,7 @@ public:
protected:
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:
@ -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<Texture> getDilatedTexture(float dilation);

View file

@ -50,7 +50,7 @@ QSharedPointer<NetworkValue> ScriptCache::getValue(const ParameterizedURL& 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));
}

View file

@ -49,7 +49,7 @@ public:
protected:
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:

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 highestPriority = -FLT_MAX;
for (QHash<QPointer<QObject>, float>::iterator it = _loadPriorities.begin(); it != _loadPriorities.end(); ) {

View file

@ -48,7 +48,7 @@ protected:
/// Creates a new resource.
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 requestCompleted();
@ -77,10 +77,13 @@ public:
void ensureLoading();
/// 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.
void clearLoadPriority(const QPointer<QObject>& owner) { _loadPriorities.remove(owner); }
virtual void clearLoadPriority(const QPointer<QObject>& owner);
/// Returns the highest load priority across all owners.
float getLoadPriority();
@ -96,6 +99,7 @@ protected:
QNetworkRequest _request;
bool _startedLoading;
bool _failedToLoad;
QHash<QPointer<QObject>, float> _loadPriorities;
private slots:
@ -110,8 +114,6 @@ private:
QNetworkReply* _reply;
int _attempts;
QHash<QPointer<QObject>, float> _loadPriorities;
};
uint qHash(const QPointer<QObject>& value, uint seed = 0);