From 9d3abe5513de58a7a51d72b42bec687487c79f1e Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 31 Mar 2016 13:24:28 -0700 Subject: [PATCH] Release texs when models are cached --- libraries/animation/src/AnimationCache.cpp | 2 +- libraries/audio/src/SoundCache.cpp | 2 +- .../src/model-networking/ModelCache.cpp | 38 +++++++++++++++---- .../src/model-networking/ModelCache.h | 13 ++++++- .../src/model-networking/ShaderCache.cpp | 2 +- .../src/model-networking/TextureCache.cpp | 3 +- libraries/networking/src/ResourceCache.h | 4 +- .../recording/src/recording/ClipCache.cpp | 2 +- 8 files changed, 50 insertions(+), 16 deletions(-) diff --git a/libraries/animation/src/AnimationCache.cpp b/libraries/animation/src/AnimationCache.cpp index ca666443fa..02d3f8873e 100644 --- a/libraries/animation/src/AnimationCache.cpp +++ b/libraries/animation/src/AnimationCache.cpp @@ -36,7 +36,7 @@ AnimationPointer AnimationCache::getAnimation(const QUrl& url) { QSharedPointer AnimationCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { - return QSharedPointer(new Animation(url), &Resource::allReferencesCleared); + return QSharedPointer(new Animation(url), &Resource::deleter); } Animation::Animation(const QUrl& url) : Resource(url) {} diff --git a/libraries/audio/src/SoundCache.cpp b/libraries/audio/src/SoundCache.cpp index a7af1bdda2..abcdb2da7c 100644 --- a/libraries/audio/src/SoundCache.cpp +++ b/libraries/audio/src/SoundCache.cpp @@ -36,5 +36,5 @@ SharedSoundPointer SoundCache::getSound(const QUrl& url) { QSharedPointer SoundCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { qCDebug(audio) << "Requesting sound at" << url.toString(); - return QSharedPointer(new Sound(url), &Resource::allReferencesCleared); + return QSharedPointer(new Sound(url), &Resource::deleter); } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 9b5666742d..89cc99ff94 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -67,15 +67,14 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) { // Get the raw GeometryResource, not the wrapped NetworkGeometry _geometryResource = modelCache->getResource(url, QUrl(), false, &extra).staticCast(); + // Avoid caching nested resources - their references will be held by the parent + _geometryResource->_isCacheable = false; if (_geometryResource->isLoaded()) { onGeometryMappingLoaded(!_geometryResource->getURL().isEmpty()); } else { connect(_geometryResource.data(), &Resource::finished, this, &GeometryMappingResource::onGeometryMappingLoaded); } - - // Avoid caching nested resources - their references will be held by the parent - _geometryResource->_isCacheable = false; } } @@ -86,6 +85,10 @@ void GeometryMappingResource::onGeometryMappingLoaded(bool success) { _meshes = _geometryResource->_meshes; _materials = _geometryResource->_materials; } + + // Avoid holding onto extra references + _geometryResource.reset(); + finishedLoading(success); } @@ -157,7 +160,7 @@ class GeometryDefinitionResource : public GeometryResource { Q_OBJECT public: GeometryDefinitionResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) : - GeometryResource(url), _mapping(mapping), _textureBaseUrl(textureBaseUrl.isValid() ? textureBaseUrl : url) {} + GeometryResource(url, textureBaseUrl.isValid() ? textureBaseUrl : url), _mapping(mapping) {} virtual void downloadFinished(const QByteArray& data) override; @@ -166,7 +169,6 @@ protected: private: QVariantHash _mapping; - QUrl _textureBaseUrl; }; void GeometryDefinitionResource::downloadFinished(const QByteArray& data) { @@ -220,13 +222,20 @@ QSharedPointer ModelCache::createResource(const QUrl& url, const QShar resource = new GeometryDefinitionResource(url, geometryExtra->mapping, geometryExtra->textureBaseUrl); } - return QSharedPointer(resource, &Resource::allReferencesCleared); + return QSharedPointer(resource, &Resource::deleter); } std::shared_ptr ModelCache::getGeometry(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) { GeometryExtra geometryExtra = { mapping, textureBaseUrl }; GeometryResource::Pointer resource = getResource(url, QUrl(), true, &geometryExtra).staticCast(); - return resource ? std::make_shared(resource) : NetworkGeometry::Pointer(); + if (resource) { + if (resource->isLoaded() && !resource->hasTextures()) { + resource->setTextures(); + } + return std::make_shared(resource); + } else { + return NetworkGeometry::Pointer(); + } } const QVariantMap Geometry::getTextures() const { @@ -313,6 +322,21 @@ const std::shared_ptr Geometry::getShapeMaterial(int shap return nullptr; } +void GeometryResource::deleter() { + resetTextures(); + Resource::deleter(); +} + +void GeometryResource::setTextures() { + for (const FBXMaterial& material : _geometry->materials) { + _materials.push_back(std::make_shared(material, _textureBaseUrl)); + } +} + +void GeometryResource::resetTextures() { + _materials.clear(); +} + NetworkGeometry::NetworkGeometry(const GeometryResource::Pointer& networkGeometry) : _resource(networkGeometry) { connect(_resource.data(), &Resource::finished, this, &NetworkGeometry::resourceFinished); connect(_resource.data(), &Resource::onRefresh, this, &NetworkGeometry::resourceRefreshed); diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index dad7883a6a..1e9dd23bae 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -99,15 +99,24 @@ class GeometryResource : public Resource, public Geometry { public: using Pointer = QSharedPointer; - GeometryResource(const QUrl& url) : Resource(url) {} + GeometryResource(const QUrl& url, const QUrl& textureBaseUrl = QUrl()) : Resource(url) {} virtual bool areTexturesLoaded() const { return isLoaded() && Geometry::areTexturesLoaded(); } + virtual void deleter() override; + protected: + friend class ModelCache; friend class GeometryMappingResource; - virtual bool isCacheable() const override { return _loaded && _isCacheable; } + // Geometries may not hold onto textures while cached - that is for the texture cache + bool hasTextures() const { return !_materials.empty(); } + void setTextures(); + void resetTextures(); + QUrl _textureBaseUrl; + + virtual bool isCacheable() const override { return _loaded && _isCacheable; } bool _isCacheable { true }; }; diff --git a/libraries/model-networking/src/model-networking/ShaderCache.cpp b/libraries/model-networking/src/model-networking/ShaderCache.cpp index 7e52052c30..3e14a99f87 100644 --- a/libraries/model-networking/src/model-networking/ShaderCache.cpp +++ b/libraries/model-networking/src/model-networking/ShaderCache.cpp @@ -28,6 +28,6 @@ NetworkShaderPointer ShaderCache::getShader(const QUrl& url) { } QSharedPointer ShaderCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { - return QSharedPointer(new NetworkShader(url, delayLoad), &Resource::allReferencesCleared); + return QSharedPointer(new NetworkShader(url, delayLoad), &Resource::deleter); } diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 28f4882b86..4cac3903a5 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -166,12 +166,11 @@ gpu::TexturePointer TextureCache::getImageTexture(const QString& path) { return texture; } - QSharedPointer TextureCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { const TextureExtra* textureExtra = static_cast(extra); return QSharedPointer(new NetworkTexture(url, textureExtra->type, textureExtra->content), - &Resource::allReferencesCleared); + &Resource::deleter); } NetworkTexture::NetworkTexture(const QUrl& url, TextureType type, const QByteArray& content) : diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 7f4d86393b..fc3d8540e6 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -191,7 +191,7 @@ public: void setCache(ResourceCache* cache) { _cache = cache; } - Q_INVOKABLE void allReferencesCleared(); + virtual void deleter() { allReferencesCleared(); } const QUrl& getURL() const { return _url; } @@ -226,6 +226,8 @@ protected: /// This should be called by subclasses that override downloadFinished to mark the end of processing. Q_INVOKABLE void finishedLoading(bool success); + Q_INVOKABLE void allReferencesCleared(); + QUrl _url; QUrl _activeUrl; bool _startedLoading = false; diff --git a/libraries/recording/src/recording/ClipCache.cpp b/libraries/recording/src/recording/ClipCache.cpp index 37c15b0ca4..145ecfc7b9 100644 --- a/libraries/recording/src/recording/ClipCache.cpp +++ b/libraries/recording/src/recording/ClipCache.cpp @@ -36,6 +36,6 @@ NetworkClipLoaderPointer ClipCache::getClipLoader(const QUrl& url) { } QSharedPointer ClipCache::createResource(const QUrl& url, const QSharedPointer& fallback, bool delayLoad, const void* extra) { - return QSharedPointer(new NetworkClipLoader(url, delayLoad), &Resource::allReferencesCleared); + return QSharedPointer(new NetworkClipLoader(url, delayLoad), &Resource::deleter); }