mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:49:05 +02:00
Merge pull request #14139 from SamGondelman/animation
Fix various ResourceCache bugs
This commit is contained in:
commit
e59e3720fe
7 changed files with 119 additions and 134 deletions
|
@ -152,6 +152,8 @@
|
||||||
#include <avatars-renderer/ScriptAvatar.h>
|
#include <avatars-renderer/ScriptAvatar.h>
|
||||||
#include <RenderableEntityItem.h>
|
#include <RenderableEntityItem.h>
|
||||||
#include <procedural/ProceduralSkybox.h>
|
#include <procedural/ProceduralSkybox.h>
|
||||||
|
#include <model-networking/MaterialCache.h>
|
||||||
|
#include "recording/ClipCache.h"
|
||||||
|
|
||||||
#include "AudioClient.h"
|
#include "AudioClient.h"
|
||||||
#include "audio/AudioScope.h"
|
#include "audio/AudioScope.h"
|
||||||
|
@ -328,9 +330,9 @@ static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
||||||
#else
|
#else
|
||||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
static const uint32_t MAX_CONCURRENT_RESOURCE_DOWNLOADS = 4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For processing on QThreadPool, we target a number of threads after reserving some
|
// For processing on QThreadPool, we target a number of threads after reserving some
|
||||||
|
@ -1327,7 +1329,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
|
|
||||||
QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads");
|
QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads");
|
||||||
bool success;
|
bool success;
|
||||||
int concurrentDownloads = concurrentDownloadsStr.toInt(&success);
|
uint32_t concurrentDownloads = concurrentDownloadsStr.toUInt(&success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
|
concurrentDownloads = MAX_CONCURRENT_RESOURCE_DOWNLOADS;
|
||||||
}
|
}
|
||||||
|
@ -2054,7 +2056,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
properties["active_downloads"] = loadingRequests.size();
|
properties["active_downloads"] = loadingRequests.size();
|
||||||
properties["pending_downloads"] = ResourceCache::getPendingRequestCount();
|
properties["pending_downloads"] = (int)ResourceCache::getPendingRequestCount();
|
||||||
properties["active_downloads_details"] = loadingRequestsStats;
|
properties["active_downloads_details"] = loadingRequestsStats;
|
||||||
|
|
||||||
auto statTracker = DependencyManager::get<StatTracker>();
|
auto statTracker = DependencyManager::get<StatTracker>();
|
||||||
|
@ -4653,8 +4655,8 @@ void Application::idle() {
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
|
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
|
||||||
}
|
}
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
PROFILE_COUNTER_IF_CHANGED(app, "renderLoopRate", float, _renderLoopCounter.rate());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
|
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", uint32_t, ResourceCache::getLoadingRequestCount());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
|
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", uint32_t, ResourceCache::getPendingRequestCount());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||||
auto renderConfig = _renderEngine->getConfiguration();
|
auto renderConfig = _renderEngine->getConfiguration();
|
||||||
|
@ -5399,13 +5401,21 @@ void Application::reloadResourceCaches() {
|
||||||
|
|
||||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
||||||
|
|
||||||
|
// Clear the entities and their renderables
|
||||||
|
getEntities()->clear();
|
||||||
|
|
||||||
DependencyManager::get<AssetClient>()->clearCache();
|
DependencyManager::get<AssetClient>()->clearCache();
|
||||||
DependencyManager::get<ScriptCache>()->clearCache();
|
DependencyManager::get<ScriptCache>()->clearCache();
|
||||||
|
|
||||||
|
// Clear all the resource caches
|
||||||
|
DependencyManager::get<ResourceCacheSharedItems>()->clear();
|
||||||
DependencyManager::get<AnimationCache>()->refreshAll();
|
DependencyManager::get<AnimationCache>()->refreshAll();
|
||||||
DependencyManager::get<ModelCache>()->refreshAll();
|
|
||||||
DependencyManager::get<SoundCache>()->refreshAll();
|
DependencyManager::get<SoundCache>()->refreshAll();
|
||||||
|
MaterialCache::instance().refreshAll();
|
||||||
|
DependencyManager::get<ModelCache>()->refreshAll();
|
||||||
|
ShaderCache::instance().refreshAll();
|
||||||
DependencyManager::get<TextureCache>()->refreshAll();
|
DependencyManager::get<TextureCache>()->refreshAll();
|
||||||
|
DependencyManager::get<recording::ClipCache>()->refreshAll();
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
|
DependencyManager::get<NodeList>()->reset(); // Force redownload of .fst models
|
||||||
|
|
||||||
|
@ -6470,9 +6480,12 @@ void Application::clearDomainOctreeDetails() {
|
||||||
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
|
skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
|
||||||
|
|
||||||
DependencyManager::get<AnimationCache>()->clearUnusedResources();
|
DependencyManager::get<AnimationCache>()->clearUnusedResources();
|
||||||
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
|
||||||
DependencyManager::get<SoundCache>()->clearUnusedResources();
|
DependencyManager::get<SoundCache>()->clearUnusedResources();
|
||||||
|
MaterialCache::instance().clearUnusedResources();
|
||||||
|
DependencyManager::get<ModelCache>()->clearUnusedResources();
|
||||||
|
ShaderCache::instance().clearUnusedResources();
|
||||||
DependencyManager::get<TextureCache>()->clearUnusedResources();
|
DependencyManager::get<TextureCache>()->clearUnusedResources();
|
||||||
|
DependencyManager::get<recording::ClipCache>()->clearUnusedResources();
|
||||||
|
|
||||||
getMyAvatar()->setAvatarEntityDataChanged(true);
|
getMyAvatar()->setAvatarEntityDataChanged(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,8 +267,8 @@ void Stats::updateStats(bool force) {
|
||||||
|
|
||||||
auto loadingRequests = ResourceCache::getLoadingRequests();
|
auto loadingRequests = ResourceCache::getLoadingRequests();
|
||||||
STAT_UPDATE(downloads, loadingRequests.size());
|
STAT_UPDATE(downloads, loadingRequests.size());
|
||||||
STAT_UPDATE(downloadLimit, ResourceCache::getRequestLimit())
|
STAT_UPDATE(downloadLimit, (int)ResourceCache::getRequestLimit())
|
||||||
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
|
STAT_UPDATE(downloadsPending, (int)ResourceCache::getPendingRequestCount());
|
||||||
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||||
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,6 @@ AnimationCache::AnimationCache(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
|
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
AnimationPointer result;
|
|
||||||
BLOCKING_INVOKE_METHOD(this, "getAnimation",
|
|
||||||
Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return getResource(url).staticCast<Animation>();
|
return getResource(url).staticCast<Animation>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,6 @@ SoundCache::SoundCache(QObject* parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
SharedSoundPointer SoundCache::getSound(const QUrl& url) {
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
SharedSoundPointer result;
|
|
||||||
BLOCKING_INVOKE_METHOD(this, "getSound",
|
|
||||||
Q_RETURN_ARG(SharedSoundPointer, result), Q_ARG(const QUrl&, url));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return getResource(url).staticCast<Sound>();
|
return getResource(url).staticCast<Sound>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ protected:
|
||||||
void makeLocalRequest();
|
void makeLocalRequest();
|
||||||
Q_INVOKABLE void handleLocalRequestCompleted();
|
Q_INVOKABLE void handleLocalRequestCompleted();
|
||||||
|
|
||||||
virtual bool isCacheable() const override { return _loaded; }
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual void downloadFinished(const QByteArray& data) override;
|
Q_INVOKABLE virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
bool handleFailedRequest(ResourceRequest::Result result) override;
|
bool handleFailedRequest(ResourceRequest::Result result) override;
|
||||||
|
|
|
@ -27,28 +27,35 @@
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
|
|
||||||
|
bool ResourceCacheSharedItems::appendRequest(QWeakPointer<Resource> resource) {
|
||||||
#define clamp(x, min, max) (((x) < (min)) ? (min) :\
|
|
||||||
(((x) > (max)) ? (max) :\
|
|
||||||
(x)))
|
|
||||||
|
|
||||||
void ResourceCacheSharedItems::appendActiveRequest(QWeakPointer<Resource> resource) {
|
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_loadingRequests.append(resource);
|
if ((uint32_t)_loadingRequests.size() < _requestLimit) {
|
||||||
|
_loadingRequests.append(resource);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
_pendingRequests.append(resource);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCacheSharedItems::appendPendingRequest(QWeakPointer<Resource> resource) {
|
void ResourceCacheSharedItems::setRequestLimit(uint32_t limit) {
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_pendingRequests.append(resource);
|
_requestLimit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QSharedPointer<Resource>> ResourceCacheSharedItems::getPendingRequests() {
|
uint32_t ResourceCacheSharedItems::getRequestLimit() const {
|
||||||
|
Lock lock(_mutex);
|
||||||
|
return _requestLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QSharedPointer<Resource>> ResourceCacheSharedItems::getPendingRequests() const {
|
||||||
QList<QSharedPointer<Resource>> result;
|
QList<QSharedPointer<Resource>> result;
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
|
|
||||||
foreach(QSharedPointer<Resource> resource, _pendingRequests) {
|
foreach (QWeakPointer<Resource> resource, _pendingRequests) {
|
||||||
if (resource) {
|
auto locked = resource.lock();
|
||||||
result.append(resource);
|
if (locked) {
|
||||||
|
result.append(locked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,16 +67,12 @@ uint32_t ResourceCacheSharedItems::getPendingRequestsCount() const {
|
||||||
return _pendingRequests.size();
|
return _pendingRequests.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QSharedPointer<Resource>> ResourceCacheSharedItems::getLoadingRequests() {
|
QList<QSharedPointer<Resource>> ResourceCacheSharedItems::getLoadingRequests() const {
|
||||||
QList<QSharedPointer<Resource>> result;
|
QList<QSharedPointer<Resource>> result;
|
||||||
Lock lock(_mutex);
|
{
|
||||||
|
Lock lock(_mutex);
|
||||||
foreach(QSharedPointer<Resource> resource, _loadingRequests) {
|
result = _loadingRequests;
|
||||||
if (resource) {
|
|
||||||
result.append(resource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +134,11 @@ QSharedPointer<Resource> ResourceCacheSharedItems::getHighestPendingRequest() {
|
||||||
return highestResource;
|
return highestResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCacheSharedItems::clear() {
|
||||||
|
Lock lock(_mutex);
|
||||||
|
_pendingRequests.clear();
|
||||||
|
_loadingRequests.clear();
|
||||||
|
}
|
||||||
|
|
||||||
ScriptableResourceCache::ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache) {
|
ScriptableResourceCache::ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache) {
|
||||||
_resourceCache = resourceCache;
|
_resourceCache = resourceCache;
|
||||||
|
@ -244,9 +252,7 @@ ResourceCache::ResourceCache(QObject* parent) : QObject(parent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceCache::~ResourceCache() {
|
ResourceCache::~ResourceCache() {}
|
||||||
clearUnusedResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::clearATPAssets() {
|
void ResourceCache::clearATPAssets() {
|
||||||
{
|
{
|
||||||
|
@ -260,6 +266,7 @@ void ResourceCache::clearATPAssets() {
|
||||||
if (auto strongRef = resource.lock()) {
|
if (auto strongRef = resource.lock()) {
|
||||||
// Make sure the resource won't reinsert itself
|
// Make sure the resource won't reinsert itself
|
||||||
strongRef->setCache(nullptr);
|
strongRef->setCache(nullptr);
|
||||||
|
_totalResourcesSize -= strongRef->getBytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,28 +276,18 @@ void ResourceCache::clearATPAssets() {
|
||||||
for (auto& resource : _unusedResources.values()) {
|
for (auto& resource : _unusedResources.values()) {
|
||||||
if (resource->getURL().scheme() == URL_SCHEME_ATP) {
|
if (resource->getURL().scheme() == URL_SCHEME_ATP) {
|
||||||
_unusedResources.remove(resource->getLRUKey());
|
_unusedResources.remove(resource->getLRUKey());
|
||||||
}
|
_unusedResourcesSize -= resource->getBytes();
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
QWriteLocker locker(&_resourcesToBeGottenLock);
|
|
||||||
auto it = _resourcesToBeGotten.begin();
|
|
||||||
while (it != _resourcesToBeGotten.end()) {
|
|
||||||
if (it->scheme() == URL_SCHEME_ATP) {
|
|
||||||
it = _resourcesToBeGotten.erase(it);
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetResourceCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::refreshAll() {
|
void ResourceCache::refreshAll() {
|
||||||
// Clear all unused resources so we don't have to reload them
|
// Clear all unused resources so we don't have to reload them
|
||||||
clearUnusedResources();
|
clearUnusedResources();
|
||||||
resetResourceCounters();
|
resetUnusedResourceCounter();
|
||||||
|
|
||||||
QHash<QUrl, QWeakPointer<Resource>> resources;
|
QHash<QUrl, QWeakPointer<Resource>> resources;
|
||||||
{
|
{
|
||||||
|
@ -306,21 +303,6 @@ void ResourceCache::refreshAll() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::refresh(const QUrl& url) {
|
|
||||||
QSharedPointer<Resource> resource;
|
|
||||||
{
|
|
||||||
QReadLocker locker(&_resourcesLock);
|
|
||||||
resource = _resources.value(url).lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource) {
|
|
||||||
resource->refresh();
|
|
||||||
} else {
|
|
||||||
removeResource(url);
|
|
||||||
resetResourceCounters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantList ResourceCache::getResourceList() {
|
QVariantList ResourceCache::getResourceList() {
|
||||||
QVariantList list;
|
QVariantList list;
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
|
@ -338,12 +320,13 @@ QVariantList ResourceCache::getResourceList() {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::setRequestLimit(int limit) {
|
void ResourceCache::setRequestLimit(uint32_t limit) {
|
||||||
_requestLimit = limit;
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
|
sharedItems->setRequestLimit(limit);
|
||||||
|
|
||||||
// Now go fill any new request spots
|
// Now go fill any new request spots
|
||||||
while (attemptHighestPriorityRequest()) {
|
while (sharedItems->getLoadingRequestsCount() < limit && sharedItems->getPendingRequestsCount() > 0) {
|
||||||
// just keep looping until we reach the new limit or no more pending requests
|
attemptHighestPriorityRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,9 +364,9 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize) {
|
void ResourceCache::setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize) {
|
||||||
_unusedResourcesMaxSize = clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE);
|
_unusedResourcesMaxSize = glm::clamp(unusedResourcesMaxSize, MIN_UNUSED_MAX_SIZE, MAX_UNUSED_MAX_SIZE);
|
||||||
reserveUnusedResource(0);
|
reserveUnusedResource(0);
|
||||||
resetResourceCounters();
|
resetUnusedResourceCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::addUnusedResource(const QSharedPointer<Resource>& resource) {
|
void ResourceCache::addUnusedResource(const QSharedPointer<Resource>& resource) {
|
||||||
|
@ -391,18 +374,20 @@ void ResourceCache::addUnusedResource(const QSharedPointer<Resource>& resource)
|
||||||
if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) {
|
if (resource->getBytes() == 0 || resource->getBytes() > _unusedResourcesMaxSize) {
|
||||||
resource->setCache(nullptr);
|
resource->setCache(nullptr);
|
||||||
removeResource(resource->getURL(), resource->getBytes());
|
removeResource(resource->getURL(), resource->getBytes());
|
||||||
resetResourceCounters();
|
resetTotalResourceCounter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reserveUnusedResource(resource->getBytes());
|
reserveUnusedResource(resource->getBytes());
|
||||||
|
|
||||||
resource->setLRUKey(++_lastLRUKey);
|
resource->setLRUKey(++_lastLRUKey);
|
||||||
_unusedResourcesSize += resource->getBytes();
|
|
||||||
|
|
||||||
resetResourceCounters();
|
{
|
||||||
|
QWriteLocker locker(&_unusedResourcesLock);
|
||||||
|
_unusedResources.insert(resource->getLRUKey(), resource);
|
||||||
|
_unusedResourcesSize += resource->getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
QWriteLocker locker(&_unusedResourcesLock);
|
resetUnusedResourceCounter();
|
||||||
_unusedResources.insert(resource->getLRUKey(), resource);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::removeUnusedResource(const QSharedPointer<Resource>& resource) {
|
void ResourceCache::removeUnusedResource(const QSharedPointer<Resource>& resource) {
|
||||||
|
@ -412,7 +397,7 @@ void ResourceCache::removeUnusedResource(const QSharedPointer<Resource>& resourc
|
||||||
_unusedResourcesSize -= resource->getBytes();
|
_unusedResourcesSize -= resource->getBytes();
|
||||||
|
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
resetResourceCounters();
|
resetUnusedResourceCounter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,14 +430,19 @@ void ResourceCache::clearUnusedResources() {
|
||||||
}
|
}
|
||||||
_unusedResources.clear();
|
_unusedResources.clear();
|
||||||
}
|
}
|
||||||
|
_unusedResourcesSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::resetResourceCounters() {
|
void ResourceCache::resetTotalResourceCounter() {
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_resourcesLock);
|
QReadLocker locker(&_resourcesLock);
|
||||||
_numTotalResources = _resources.size();
|
_numTotalResources = _resources.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceCache::resetUnusedResourceCounter() {
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_unusedResourcesLock);
|
QReadLocker locker(&_unusedResourcesLock);
|
||||||
_numUnusedResources = _unusedResources.size();
|
_numUnusedResources = _unusedResources.size();
|
||||||
|
@ -461,6 +451,13 @@ void ResourceCache::resetResourceCounters() {
|
||||||
emit dirty();
|
emit dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCache::resetResourceCounters() {
|
||||||
|
resetTotalResourceCounter();
|
||||||
|
resetUnusedResourceCounter();
|
||||||
|
|
||||||
|
emit dirty();
|
||||||
|
}
|
||||||
|
|
||||||
void ResourceCache::removeResource(const QUrl& url, qint64 size) {
|
void ResourceCache::removeResource(const QUrl& url, qint64 size) {
|
||||||
QWriteLocker locker(&_resourcesLock);
|
QWriteLocker locker(&_resourcesLock);
|
||||||
_resources.remove(url);
|
_resources.remove(url);
|
||||||
|
@ -481,38 +478,34 @@ QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() {
|
||||||
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
|
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ResourceCache::getPendingRequestCount() {
|
uint32_t ResourceCache::getPendingRequestCount() {
|
||||||
return DependencyManager::get<ResourceCacheSharedItems>()->getPendingRequestsCount();
|
return DependencyManager::get<ResourceCacheSharedItems>()->getPendingRequestsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ResourceCache::getLoadingRequestCount() {
|
uint32_t ResourceCache::getLoadingRequestCount() {
|
||||||
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequestsCount();
|
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequestsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceCache::attemptRequest(QSharedPointer<Resource> resource) {
|
bool ResourceCache::attemptRequest(QSharedPointer<Resource> resource) {
|
||||||
Q_ASSERT(!resource.isNull());
|
Q_ASSERT(!resource.isNull());
|
||||||
|
|
||||||
|
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
if (_requestsActive >= _requestLimit) {
|
if (sharedItems->appendRequest(resource)) {
|
||||||
// wait until a slot becomes available
|
resource->makeRequest();
|
||||||
sharedItems->appendPendingRequest(resource);
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
++_requestsActive;
|
|
||||||
sharedItems->appendActiveRequest(resource);
|
|
||||||
resource->makeRequest();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::requestCompleted(QWeakPointer<Resource> resource) {
|
void ResourceCache::requestCompleted(QWeakPointer<Resource> resource) {
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
|
|
||||||
sharedItems->removeRequest(resource);
|
sharedItems->removeRequest(resource);
|
||||||
--_requestsActive;
|
|
||||||
|
|
||||||
attemptHighestPriorityRequest();
|
// Now go fill any new request spots
|
||||||
|
while (sharedItems->getLoadingRequestsCount() < sharedItems->getRequestLimit() && sharedItems->getPendingRequestsCount() > 0) {
|
||||||
|
attemptHighestPriorityRequest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResourceCache::attemptHighestPriorityRequest() {
|
bool ResourceCache::attemptHighestPriorityRequest() {
|
||||||
|
@ -521,10 +514,6 @@ bool ResourceCache::attemptHighestPriorityRequest() {
|
||||||
return (resource && attemptRequest(resource));
|
return (resource && attemptRequest(resource));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int DEFAULT_REQUEST_LIMIT = 10;
|
|
||||||
int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT;
|
|
||||||
int ResourceCache::_requestsActive = 0;
|
|
||||||
|
|
||||||
static int requestID = 0;
|
static int requestID = 0;
|
||||||
|
|
||||||
Resource::Resource(const QUrl& url) :
|
Resource::Resource(const QUrl& url) :
|
||||||
|
@ -550,7 +539,7 @@ void Resource::ensureLoading() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::setLoadPriority(const QPointer<QObject>& owner, float priority) {
|
void Resource::setLoadPriority(const QPointer<QObject>& owner, float priority) {
|
||||||
if (!(_failedToLoad)) {
|
if (!_failedToLoad) {
|
||||||
_loadPriorities.insert(owner, priority);
|
_loadPriorities.insert(owner, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,7 +555,7 @@ void Resource::setLoadPriorities(const QHash<QPointer<QObject>, float>& prioriti
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::clearLoadPriority(const QPointer<QObject>& owner) {
|
void Resource::clearLoadPriority(const QPointer<QObject>& owner) {
|
||||||
if (!(_failedToLoad)) {
|
if (!_failedToLoad) {
|
||||||
_loadPriorities.remove(owner);
|
_loadPriorities.remove(owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,6 +581,7 @@ void Resource::refresh() {
|
||||||
if (_request && !(_loaded || _failedToLoad)) {
|
if (_request && !(_loaded || _failedToLoad)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_request) {
|
if (_request) {
|
||||||
_request->disconnect(this);
|
_request->disconnect(this);
|
||||||
_request->deleteLater();
|
_request->deleteLater();
|
||||||
|
@ -613,7 +603,7 @@ void Resource::allReferencesCleared() {
|
||||||
|
|
||||||
if (_cache && isCacheable()) {
|
if (_cache && isCacheable()) {
|
||||||
// create and reinsert new shared pointer
|
// create and reinsert new shared pointer
|
||||||
QSharedPointer<Resource> self(this, &Resource::allReferencesCleared);
|
QSharedPointer<Resource> self(this, &Resource::deleter);
|
||||||
setSelf(self);
|
setSelf(self);
|
||||||
reinsert();
|
reinsert();
|
||||||
|
|
||||||
|
@ -623,7 +613,7 @@ void Resource::allReferencesCleared() {
|
||||||
if (_cache) {
|
if (_cache) {
|
||||||
// remove from the cache
|
// remove from the cache
|
||||||
_cache->removeResource(getURL(), getBytes());
|
_cache->removeResource(getURL(), getBytes());
|
||||||
_cache->resetResourceCounters();
|
_cache->resetTotalResourceCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
|
@ -732,6 +722,7 @@ void Resource::handleReplyFinished() {
|
||||||
{ "from_cache", false },
|
{ "from_cache", false },
|
||||||
{ "size_mb", _bytesTotal / 1000000.0 }
|
{ "size_mb", _bytesTotal / 1000000.0 }
|
||||||
});
|
});
|
||||||
|
ResourceCache::requestCompleted(_self);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,21 +66,25 @@ class ResourceCacheSharedItems : public Dependency {
|
||||||
using Lock = std::unique_lock<Mutex>;
|
using Lock = std::unique_lock<Mutex>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void appendPendingRequest(QWeakPointer<Resource> newRequest);
|
bool appendRequest(QWeakPointer<Resource> newRequest);
|
||||||
void appendActiveRequest(QWeakPointer<Resource> newRequest);
|
|
||||||
void removeRequest(QWeakPointer<Resource> doneRequest);
|
void removeRequest(QWeakPointer<Resource> doneRequest);
|
||||||
QList<QSharedPointer<Resource>> getPendingRequests();
|
void setRequestLimit(uint32_t limit);
|
||||||
uint32_t getPendingRequestsCount() const;
|
uint32_t getRequestLimit() const;
|
||||||
QList<QSharedPointer<Resource>> getLoadingRequests();
|
QList<QSharedPointer<Resource>> getPendingRequests() const;
|
||||||
QSharedPointer<Resource> getHighestPendingRequest();
|
QSharedPointer<Resource> getHighestPendingRequest();
|
||||||
|
uint32_t getPendingRequestsCount() const;
|
||||||
|
QList<QSharedPointer<Resource>> getLoadingRequests() const;
|
||||||
uint32_t getLoadingRequestsCount() const;
|
uint32_t getLoadingRequestsCount() const;
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceCacheSharedItems() = default;
|
ResourceCacheSharedItems() = default;
|
||||||
|
|
||||||
mutable Mutex _mutex;
|
mutable Mutex _mutex;
|
||||||
QList<QWeakPointer<Resource>> _pendingRequests;
|
QList<QWeakPointer<Resource>> _pendingRequests;
|
||||||
QList<QWeakPointer<Resource>> _loadingRequests;
|
QList<QSharedPointer<Resource>> _loadingRequests;
|
||||||
|
const uint32_t DEFAULT_REQUEST_LIMIT = 10;
|
||||||
|
uint32_t _requestLimit { DEFAULT_REQUEST_LIMIT };
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Wrapper to expose resources to JS/QML
|
/// Wrapper to expose resources to JS/QML
|
||||||
|
@ -200,25 +204,20 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE QVariantList getResourceList();
|
Q_INVOKABLE QVariantList getResourceList();
|
||||||
|
|
||||||
static void setRequestLimit(int limit);
|
static void setRequestLimit(uint32_t limit);
|
||||||
static int getRequestLimit() { return _requestLimit; }
|
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
|
||||||
|
|
||||||
static int getRequestsActive() { return _requestsActive; }
|
|
||||||
|
|
||||||
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
||||||
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
||||||
|
|
||||||
static QList<QSharedPointer<Resource>> getLoadingRequests();
|
static QList<QSharedPointer<Resource>> getLoadingRequests();
|
||||||
|
static uint32_t getPendingRequestCount();
|
||||||
static int getPendingRequestCount();
|
static uint32_t getLoadingRequestCount();
|
||||||
|
|
||||||
static int getLoadingRequestCount();
|
|
||||||
|
|
||||||
ResourceCache(QObject* parent = nullptr);
|
ResourceCache(QObject* parent = nullptr);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
void refresh(const QUrl& url);
|
|
||||||
void clearUnusedResources();
|
void clearUnusedResources();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -272,11 +271,11 @@ private:
|
||||||
friend class ScriptableResourceCache;
|
friend class ScriptableResourceCache;
|
||||||
|
|
||||||
void reserveUnusedResource(qint64 resourceSize);
|
void reserveUnusedResource(qint64 resourceSize);
|
||||||
void resetResourceCounters();
|
|
||||||
void removeResource(const QUrl& url, qint64 size = 0);
|
void removeResource(const QUrl& url, qint64 size = 0);
|
||||||
|
|
||||||
static int _requestLimit;
|
void resetTotalResourceCounter();
|
||||||
static int _requestsActive;
|
void resetUnusedResourceCounter();
|
||||||
|
void resetResourceCounters();
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
QHash<QUrl, QWeakPointer<Resource>> _resources;
|
QHash<QUrl, QWeakPointer<Resource>> _resources;
|
||||||
|
@ -293,10 +292,6 @@ private:
|
||||||
|
|
||||||
std::atomic<size_t> _numUnusedResources { 0 };
|
std::atomic<size_t> _numUnusedResources { 0 };
|
||||||
std::atomic<qint64> _unusedResourcesSize { 0 };
|
std::atomic<qint64> _unusedResourcesSize { 0 };
|
||||||
|
|
||||||
// Pending resources
|
|
||||||
QQueue<QUrl> _resourcesToBeGotten;
|
|
||||||
QReadWriteLock _resourcesToBeGottenLock { QReadWriteLock::Recursive };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Wrapper to expose resource caches to JS/QML
|
/// Wrapper to expose resource caches to JS/QML
|
||||||
|
@ -455,7 +450,7 @@ protected:
|
||||||
virtual void makeRequest();
|
virtual void makeRequest();
|
||||||
|
|
||||||
/// Checks whether the resource is cacheable.
|
/// Checks whether the resource is cacheable.
|
||||||
virtual bool isCacheable() const { return true; }
|
virtual bool isCacheable() const { return _loaded; }
|
||||||
|
|
||||||
/// Called when the download has finished.
|
/// Called when the download has finished.
|
||||||
/// This should be overridden by subclasses that need to process the data once it is downloaded.
|
/// This should be overridden by subclasses that need to process the data once it is downloaded.
|
||||||
|
|
Loading…
Reference in a new issue