mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 06:24:41 +02:00
set up a way to request ResourceCache downloads from a non-networking thread.
This commit is contained in:
parent
43b30c7ffa
commit
7da87d6e15
8 changed files with 73 additions and 29 deletions
|
@ -344,6 +344,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
||||||
// put the NodeList and datagram processing on the node thread
|
// put the NodeList and datagram processing on the node thread
|
||||||
nodeList->moveToThread(nodeThread);
|
nodeList->moveToThread(nodeThread);
|
||||||
|
|
||||||
|
// geometry background downloads need to happen on the Datagram Processor Thread. The idle loop will
|
||||||
|
// emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background
|
||||||
|
// downloads.
|
||||||
|
QSharedPointer<GeometryCache> geometryCacheP = DependencyManager::get<GeometryCache>();
|
||||||
|
ResourceCache *geometryCache = geometryCacheP.data();
|
||||||
|
connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets);
|
||||||
|
|
||||||
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
|
// connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
|
||||||
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams);
|
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams);
|
||||||
|
|
||||||
|
@ -1569,6 +1576,9 @@ void Application::idle() {
|
||||||
idleTimer->start(2);
|
idleTimer->start(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for any requested background downloads.
|
||||||
|
emit checkBackgroundDownloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFullscreen(bool fullscreen) {
|
void Application::setFullscreen(bool fullscreen) {
|
||||||
|
@ -3140,7 +3150,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
||||||
int viewport[4];
|
int viewport[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
|
|
||||||
bool eyeRelativeCamera = false;
|
// bool eyeRelativeCamera = false;
|
||||||
if (billboard) {
|
if (billboard) {
|
||||||
_mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees
|
_mirrorCamera.setFieldOfView(BILLBOARD_FIELD_OF_VIEW); // degees
|
||||||
_mirrorCamera.setPosition(_myAvatar->getPosition() +
|
_mirrorCamera.setPosition(_myAvatar->getPosition() +
|
||||||
|
|
|
@ -333,6 +333,8 @@ signals:
|
||||||
|
|
||||||
void svoImportRequested(const QString& url);
|
void svoImportRequested(const QString& url);
|
||||||
|
|
||||||
|
void checkBackgroundDownloads();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void domainChanged(const QString& domainHostname);
|
void domainChanged(const QString& domainHostname);
|
||||||
void updateWindowTitle();
|
void updateWindowTitle();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "NetworkAccessManager.h"
|
#include "NetworkAccessManager.h"
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
|
@ -48,32 +49,42 @@ void ResourceCache::refresh(const QUrl& url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback,
|
void ResourceCache::getResourceAsynchronously(const QUrl& url) {
|
||||||
bool delayLoad, void* extra, bool block) {
|
qDebug() << "ResourceCache::getResourceAsynchronously" << url.toString();
|
||||||
if (QThread::currentThread() != thread()) {
|
_resourcesToBeGottenLock.lockForWrite();
|
||||||
// This will re-call this method in the main thread. If block is true and the main thread
|
_resourcesToBeGotten.enqueue(QUrl(url));
|
||||||
// is waiting on a lock, we'll deadlock here.
|
_resourcesToBeGottenLock.unlock();
|
||||||
if (block) {
|
|
||||||
QSharedPointer<Resource> result;
|
|
||||||
QMetaObject::invokeMethod(this, "getResource", Qt::BlockingQueuedConnection,
|
|
||||||
Q_RETURN_ARG(QSharedPointer<Resource>, result), Q_ARG(const QUrl&, url),
|
|
||||||
Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra));
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
// Queue the re-invocation of this method, but if the main thread is blocked, don't wait. The
|
|
||||||
// return value may be NULL -- it's expected that this will be called again later, in order
|
|
||||||
// to receive the actual Resource.
|
|
||||||
QMetaObject::invokeMethod(this, "getResource", Qt::QueuedConnection,
|
|
||||||
Q_ARG(const QUrl&, url),
|
|
||||||
Q_ARG(const QUrl&, fallback), Q_ARG(bool, delayLoad), Q_ARG(void*, extra));
|
|
||||||
return _resources.value(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCache::checkAsynchronousGets() {
|
||||||
|
assert(QThread::currentThread() == thread());
|
||||||
|
_resourcesToBeGottenLock.lockForRead();
|
||||||
|
if (_resourcesToBeGotten.isEmpty()) {
|
||||||
|
_resourcesToBeGottenLock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QUrl url = _resourcesToBeGotten.dequeue();
|
||||||
|
_resourcesToBeGottenLock.unlock();
|
||||||
|
getResource(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback,
|
||||||
|
bool delayLoad, void* extra) {
|
||||||
|
QSharedPointer<Resource> resource = _resources.value(url);
|
||||||
|
if (!resource.isNull()) {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
assert(delayLoad);
|
||||||
|
getResourceAsynchronously(url);
|
||||||
|
return QSharedPointer<Resource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!url.isValid() && !url.isEmpty() && fallback.isValid()) {
|
if (!url.isValid() && !url.isEmpty() && fallback.isValid()) {
|
||||||
return getResource(fallback, QUrl(), delayLoad);
|
return getResource(fallback, QUrl(), delayLoad);
|
||||||
}
|
}
|
||||||
QSharedPointer<Resource> resource = _resources.value(url);
|
|
||||||
if (resource.isNull()) {
|
if (resource.isNull()) {
|
||||||
resource = createResource(url, fallback.isValid() ?
|
resource = createResource(url, fallback.isValid() ?
|
||||||
getResource(fallback, QUrl(), true) : QSharedPointer<Resource>(), delayLoad, extra);
|
getResource(fallback, QUrl(), true) : QSharedPointer<Resource>(), delayLoad, extra);
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QWeakPointer>
|
#include <QWeakPointer>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
#include <QQueue>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
@ -79,6 +81,9 @@ public:
|
||||||
|
|
||||||
void refresh(const QUrl& url);
|
void refresh(const QUrl& url);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void checkAsynchronousGets();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
qint64 _unusedResourcesMaxSize = DEFAULT_UNUSED_MAX_SIZE;
|
qint64 _unusedResourcesMaxSize = DEFAULT_UNUSED_MAX_SIZE;
|
||||||
qint64 _unusedResourcesSize = 0;
|
qint64 _unusedResourcesSize = 0;
|
||||||
|
@ -89,7 +94,7 @@ protected:
|
||||||
/// \param delayLoad if true, don't load the resource immediately; wait until load is first requested
|
/// \param delayLoad if true, don't load the resource immediately; wait until load is first requested
|
||||||
/// \param extra extra data to pass to the creator, if appropriate
|
/// \param extra extra data to pass to the creator, if appropriate
|
||||||
Q_INVOKABLE QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
|
Q_INVOKABLE QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
|
||||||
bool delayLoad = false, void* extra = NULL, bool block = true);
|
bool delayLoad = false, void* extra = NULL);
|
||||||
|
|
||||||
/// Creates a new resource.
|
/// Creates a new resource.
|
||||||
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
virtual QSharedPointer<Resource> createResource(const QUrl& url,
|
||||||
|
@ -109,6 +114,11 @@ private:
|
||||||
int _lastLRUKey = 0;
|
int _lastLRUKey = 0;
|
||||||
|
|
||||||
static int _requestLimit;
|
static int _requestLimit;
|
||||||
|
|
||||||
|
void getResourceAsynchronously(const QUrl& url);
|
||||||
|
QReadWriteLock _resourcesToBeGottenLock;
|
||||||
|
QQueue<QUrl> _resourcesToBeGotten;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for resources.
|
/// Base class for resources.
|
||||||
|
|
|
@ -1770,8 +1770,8 @@ void GeometryCache::renderLine(const glm::vec2& p1, const glm::vec2& p2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad, bool block) {
|
QSharedPointer<NetworkGeometry> GeometryCache::getGeometry(const QUrl& url, const QUrl& fallback, bool delayLoad) {
|
||||||
return getResource(url, fallback, delayLoad, NULL, block).staticCast<NetworkGeometry>();
|
return getResource(url, fallback, delayLoad, NULL).staticCast<NetworkGeometry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url,
|
QSharedPointer<Resource> GeometryCache::createResource(const QUrl& url,
|
||||||
|
|
|
@ -203,8 +203,7 @@ public:
|
||||||
/// Loads geometry from the specified URL.
|
/// Loads geometry from the specified URL.
|
||||||
/// \param fallback a fallback URL to load if the desired one is unavailable
|
/// \param fallback a fallback URL to load if the desired one is unavailable
|
||||||
/// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested
|
/// \param delayLoad if true, don't load the geometry immediately; wait until load is first requested
|
||||||
QSharedPointer<NetworkGeometry> getGeometry(const QUrl& url, const QUrl& fallback = QUrl(),
|
QSharedPointer<NetworkGeometry> getGeometry(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false);
|
||||||
bool delayLoad = false, bool block = true);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -325,6 +325,8 @@ void Model::init() {
|
||||||
_skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel));
|
_skinTranslucentProgram = gpu::ShaderPointer(gpu::Shader::createProgram(skinModelVertex, modelTranslucentPixel));
|
||||||
makeResult = gpu::Shader::makeProgram(*_skinTranslucentProgram, slotBindings);
|
makeResult = gpu::Shader::makeProgram(*_skinTranslucentProgram, slotBindings);
|
||||||
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations);
|
||||||
|
|
||||||
|
(void) makeResult; // quiet compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,12 +1034,22 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setCollisionModelURL(const QUrl& url, const QUrl& fallback, bool delayLoad) {
|
|
||||||
|
const QSharedPointer<NetworkGeometry> Model::getCollisionGeometry(bool delayLoad)
|
||||||
|
{
|
||||||
|
if (_collisionGeometry.isNull() && !_collisionUrl.isEmpty()) {
|
||||||
|
_collisionGeometry = DependencyManager::get<GeometryCache>()->getGeometry(_collisionUrl, QUrl(), delayLoad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _collisionGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::setCollisionModelURL(const QUrl& url) {
|
||||||
if (_collisionUrl == url) {
|
if (_collisionUrl == url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_collisionUrl = url;
|
_collisionUrl = url;
|
||||||
_collisionGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, fallback, delayLoad);
|
_collisionGeometry = DependencyManager::get<GeometryCache>()->getGeometry(url, QUrl(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const {
|
bool Model::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position) const {
|
||||||
|
|
|
@ -109,7 +109,7 @@ public:
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
|
|
||||||
// Set the model to use for collisions
|
// Set the model to use for collisions
|
||||||
Q_INVOKABLE void setCollisionModelURL(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false);
|
Q_INVOKABLE void setCollisionModelURL(const QUrl& url);
|
||||||
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
const QUrl& getCollisionURL() const { return _collisionUrl; }
|
||||||
|
|
||||||
/// Sets the distance parameter used for LOD computations.
|
/// Sets the distance parameter used for LOD computations.
|
||||||
|
@ -134,7 +134,7 @@ public:
|
||||||
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
|
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
|
||||||
|
|
||||||
/// Returns a reference to the shared collision geometry.
|
/// Returns a reference to the shared collision geometry.
|
||||||
const QSharedPointer<NetworkGeometry> getCollisionGeometry() {return _collisionGeometry; }
|
const QSharedPointer<NetworkGeometry> getCollisionGeometry(bool delayLoad = true);
|
||||||
|
|
||||||
/// Returns the number of joint states in the model.
|
/// Returns the number of joint states in the model.
|
||||||
int getJointStateCount() const { return _jointStates.size(); }
|
int getJointStateCount() const { return _jointStates.size(); }
|
||||||
|
|
Loading…
Reference in a new issue