summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-07-17 17:31:08 +0200
committerSean Harmer <sean.harmer@kdab.com>2014-07-22 19:32:30 +0200
commit9ac64d1aa090416db7aec00d1136b8d625e40a2c (patch)
treebc3adc463e953dd4ad5e543d713956d6109f04f3
parent0f0bf28b05e5d08767aa98f83dc6d5c898cdcc17 (diff)
QResourcesManager cleanup
If a resource managed by a QResourcesManager has declared a Q_DECLARE_RESOURCE_INFO(Resource, Q_REQUIRES_CLEANUP); in its header, a call to Resource->cleanup() will be performed when the resource is released. Note: Needs the next patch to compile Change-Id: Icef073c90f44a8e43a07adb5b9a496b86d7a4398 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/core/resources/qresourcesmanager.h62
-rw-r--r--src/render/backend/effectmanager.h2
-rw-r--r--src/render/backend/entitymanager.h5
-rw-r--r--src/render/backend/layermanager.h2
-rw-r--r--src/render/backend/lightmanager.h2
-rw-r--r--src/render/backend/materialmanager.cpp6
-rw-r--r--src/render/backend/materialmanager.h8
-rw-r--r--src/render/backend/meshmanager.h3
-rw-r--r--src/render/backend/rendercamera.cpp5
-rw-r--r--src/render/backend/rendercamera.h1
-rw-r--r--src/render/backend/rendereffect.cpp5
-rw-r--r--src/render/backend/rendereffect.h1
-rw-r--r--src/render/backend/renderlayer.cpp5
-rw-r--r--src/render/backend/renderlayer.h1
-rw-r--r--src/render/backend/renderlight.cpp5
-rw-r--r--src/render/backend/renderlight.h1
-rw-r--r--src/render/backend/rendermaterial.cpp16
-rw-r--r--src/render/backend/rendermaterial.h1
-rw-r--r--src/render/backend/rendermesh.cpp5
-rw-r--r--src/render/backend/rendermesh.h1
-rw-r--r--src/render/backend/renderpassmanager.h3
-rw-r--r--src/render/backend/renderrenderpass.cpp11
-rw-r--r--src/render/backend/renderrenderpass.h2
-rw-r--r--src/render/backend/rendertechnique.cpp5
-rw-r--r--src/render/backend/rendertechnique.h1
-rw-r--r--src/render/backend/techniquemanager.h2
26 files changed, 154 insertions, 7 deletions
diff --git a/src/core/resources/qresourcesmanager.h b/src/core/resources/qresourcesmanager.h
index b07d5cf7a..c98741747 100644
--- a/src/core/resources/qresourcesmanager.h
+++ b/src/core/resources/qresourcesmanager.h
@@ -134,6 +134,47 @@ private:
QReadWriteLock m_lock;
};
+template <typename T>
+struct QResourceInfo
+{
+ enum
+ {
+ needsCleanup = false
+ };
+};
+
+template <>
+struct QResourceInfo<void>
+{
+ enum
+ {
+ needsCleanup = false
+ };
+};
+
+enum
+{
+ Q_REQUIRES_CLEANUP = 0
+};
+
+#define Q_DECLARE_RESOURCE_INFO(TYPE, FLAGS) \
+template<> \
+struct QResourceInfo<TYPE > \
+{ \
+ enum \
+ { \
+ needsCleanup = ((FLAGS & Q_REQUIRES_CLEANUP) == 0) \
+ }; \
+}
+
+template <int v>
+struct Int2Type
+{
+ enum
+ {
+ value = v
+ };
+};
template <typename T, int INDEXBITS>
@@ -160,6 +201,7 @@ public:
{
if (m_resourcesToIndices.contains(r)) {
int idx = m_resourcesToIndices.take(r);
+ performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>());
m_resourcesEntries[idx] = T();
m_freeEntryIndices.append(idx);
}
@@ -179,6 +221,14 @@ private:
QList<int> m_freeEntryIndices;
QHash<T*, int> m_resourcesToIndices;
+ void performCleanup(T *r, Int2Type<true>)
+ {
+ r->cleanup();
+ }
+
+ void performCleanup(T *, Int2Type<false>)
+ {}
+
};
template <typename T, int INDEXBITS>
@@ -201,6 +251,7 @@ public:
void releaseResource(T *r)
{
if (m_resourcesToIndices.contains(r)) {
+ performCleanup(r, Int2Type<QResourceInfo<T>::needsCleanup>());
m_resourcesEntries.removeAt(m_resourcesToIndices[r]);
}
}
@@ -213,6 +264,14 @@ public:
private:
QList<T> m_resourcesEntries;
QHash<T*, int> m_resourcesToIndices;
+
+ void performCleanup(T *r, Int2Type<true>)
+ {
+ r->cleanup();
+ }
+
+ void performCleanup(T *, Int2Type<false>)
+ {}
};
template <typename T, typename C, int INDEXBITS = 16,
@@ -252,8 +311,8 @@ public:
typename LockingPolicy<QResourcesManager>::WriteLocker(this);
m_handleToResourceMapper.remove(m_handleToResourceMapper.key(handle));
T *val = m_handleManager.data(handle);
- AllocatingPolicy<T, INDEXBITS>::releaseResource(val);
m_handleManager.release(handle);
+ AllocatingPolicy<T, INDEXBITS>::releaseResource(val);
}
void reset()
@@ -326,6 +385,7 @@ protected:
QHandleManager<T, INDEXBITS> m_handleManager;
QHash<C, QHandle<T, INDEXBITS> > m_handleToResourceMapper;
int m_maxResourcesEntries;
+
};
}// Qt3D
diff --git a/src/render/backend/effectmanager.h b/src/render/backend/effectmanager.h
index 53611ff9a..e4dd8b728 100644
--- a/src/render/backend/effectmanager.h
+++ b/src/render/backend/effectmanager.h
@@ -68,6 +68,8 @@ public:
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderEffect, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/entitymanager.h b/src/render/backend/entitymanager.h
index 3ecc5144f..5aa0a5b95 100644
--- a/src/render/backend/entitymanager.h
+++ b/src/render/backend/entitymanager.h
@@ -65,12 +65,17 @@ public:
inline RenderEntity *getOrCreateRenderNode(const QUuid &id) { return getOrCreateResource(id); }
inline RenderEntity *renderNode(const QUuid &id) { return lookupResource(id); }
inline void releaseRenderNode(const QUuid &id) { releaseResource(id); }
+
+
};
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderEntity, Q_REQUIRES_CLEANUP);
+
} // Qt3D
+
QT_END_NAMESPACE
#endif // QT3D_RENDER_RENDERNODESMANAGER_H
diff --git a/src/render/backend/layermanager.h b/src/render/backend/layermanager.h
index 766ae7ede..8db4329c8 100644
--- a/src/render/backend/layermanager.h
+++ b/src/render/backend/layermanager.h
@@ -66,6 +66,8 @@ public:
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderLayer, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/lightmanager.h b/src/render/backend/lightmanager.h
index d97e7472c..37efda282 100644
--- a/src/render/backend/lightmanager.h
+++ b/src/render/backend/lightmanager.h
@@ -66,6 +66,8 @@ public:
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderLight, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/materialmanager.cpp b/src/render/backend/materialmanager.cpp
index 3eddbe30a..906f75aa8 100644
--- a/src/render/backend/materialmanager.cpp
+++ b/src/render/backend/materialmanager.cpp
@@ -48,7 +48,11 @@ namespace Qt3D {
namespace Render {
MaterialManager::MaterialManager() :
- QResourcesManager<RenderMaterial, QUuid, 16>()
+ QResourcesManager<RenderMaterial,
+ QUuid,
+ 16,
+ Qt3D::ArrayAllocatingPolicy,
+ Qt3D::ObjectLevelLockingPolicy>()
{
}
diff --git a/src/render/backend/materialmanager.h b/src/render/backend/materialmanager.h
index 7147ee2de..0b2ed2b85 100644
--- a/src/render/backend/materialmanager.h
+++ b/src/render/backend/materialmanager.h
@@ -57,7 +57,11 @@ namespace Render {
typedef QHandle<RenderMaterial, 16> HMaterial;
-class MaterialManager : public QResourcesManager<RenderMaterial, QUuid, 16>
+class MaterialManager : public QResourcesManager<RenderMaterial,
+ QUuid,
+ 16,
+ Qt3D::ArrayAllocatingPolicy,
+ Qt3D::ObjectLevelLockingPolicy>
{
public:
MaterialManager();
@@ -65,6 +69,8 @@ public:
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderMaterial, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/meshmanager.h b/src/render/backend/meshmanager.h
index e4588677d..9db8c1a9e 100644
--- a/src/render/backend/meshmanager.h
+++ b/src/render/backend/meshmanager.h
@@ -68,10 +68,13 @@ public:
inline RenderMesh *getOrCreateRenderMesh(const QUuid &id) { return getOrCreateResource(id); }
inline RenderMesh *renderMesh(const QUuid &id) { return lookupResource(id); }
inline void releaseRenderMesh(const QUuid &id) { releaseResource(id); }
+
};
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderMesh, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/rendercamera.cpp b/src/render/backend/rendercamera.cpp
index 1e86328e3..ea4d5d3e5 100644
--- a/src/render/backend/rendercamera.cpp
+++ b/src/render/backend/rendercamera.cpp
@@ -66,6 +66,11 @@ RenderCamera::RenderCamera()
RenderCamera::~RenderCamera()
{
+ cleanup();
+}
+
+void RenderCamera::cleanup()
+{
if (m_peer)
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
}
diff --git a/src/render/backend/rendercamera.h b/src/render/backend/rendercamera.h
index af32d6891..00a573911 100644
--- a/src/render/backend/rendercamera.h
+++ b/src/render/backend/rendercamera.h
@@ -62,6 +62,7 @@ class RenderCamera : public QObserverInterface
public:
RenderCamera();
~RenderCamera();
+ void cleanup();
void setRenderer(Renderer *renderer);
void setPeer(QCameraLens *peer);
diff --git a/src/render/backend/rendereffect.cpp b/src/render/backend/rendereffect.cpp
index 39c936000..bd2912278 100644
--- a/src/render/backend/rendereffect.cpp
+++ b/src/render/backend/rendereffect.cpp
@@ -65,6 +65,11 @@ RenderEffect::RenderEffect()
RenderEffect::~RenderEffect()
{
+ cleanup();
+}
+
+void RenderEffect::cleanup()
+{
if (m_renderer != Q_NULLPTR && m_peer != Q_NULLPTR)
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
}
diff --git a/src/render/backend/rendereffect.h b/src/render/backend/rendereffect.h
index ef4db0f15..bc5c0d51c 100644
--- a/src/render/backend/rendereffect.h
+++ b/src/render/backend/rendereffect.h
@@ -64,6 +64,7 @@ class RenderEffect
public:
RenderEffect();
~RenderEffect();
+ void cleanup();
void setPeer(QAbstractEffect *effect);
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/renderlayer.cpp b/src/render/backend/renderlayer.cpp
index a2c11f00c..29f186e22 100644
--- a/src/render/backend/renderlayer.cpp
+++ b/src/render/backend/renderlayer.cpp
@@ -61,6 +61,11 @@ RenderLayer::RenderLayer()
RenderLayer::~RenderLayer()
{
+ cleanup();
+}
+
+void RenderLayer::cleanup()
+{
if (m_peer) {
QChangeArbiter *arbiter = m_renderer->rendererAspect()->aspectManager()->changeArbiter();
arbiter->unregisterObserver(this, m_peer);
diff --git a/src/render/backend/renderlayer.h b/src/render/backend/renderlayer.h
index 0e6458434..614d8f889 100644
--- a/src/render/backend/renderlayer.h
+++ b/src/render/backend/renderlayer.h
@@ -60,6 +60,7 @@ class RenderLayer : public QObserverInterface
public:
RenderLayer();
~RenderLayer();
+ void cleanup();
void setPeer(QLayer *peer);
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/renderlight.cpp b/src/render/backend/renderlight.cpp
index e28e3446a..6bf36ca69 100644
--- a/src/render/backend/renderlight.cpp
+++ b/src/render/backend/renderlight.cpp
@@ -61,6 +61,11 @@ RenderLight::RenderLight()
RenderLight::~RenderLight()
{
+ cleanup();
+}
+
+void RenderLight::cleanup()
+{
if (m_peer)
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
}
diff --git a/src/render/backend/renderlight.h b/src/render/backend/renderlight.h
index d279b9407..00b68d65f 100644
--- a/src/render/backend/renderlight.h
+++ b/src/render/backend/renderlight.h
@@ -60,6 +60,7 @@ class RenderLight : public QObserverInterface
public:
RenderLight();
~RenderLight();
+ void cleanup();
void setPeer(QAbstractLight *peer);
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/rendermaterial.cpp b/src/render/backend/rendermaterial.cpp
index 3cf41d1c9..cfb5c3ca1 100644
--- a/src/render/backend/rendermaterial.cpp
+++ b/src/render/backend/rendermaterial.cpp
@@ -68,21 +68,29 @@ RenderMaterial::RenderMaterial()
RenderMaterial::~RenderMaterial()
{
- if (m_renderer != Q_NULLPTR && m_peer != Q_NULLPTR)
+ cleanup();
+}
+
+void RenderMaterial::cleanup()
+{
+ if (m_renderer != Q_NULLPTR && m_peer != Q_NULLPTR) {
+ m_parameterPack.clear(); // Has to be done before the RenderMaterial is deleted
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
+ }
}
void RenderMaterial::setPeer(QMaterial *mat)
{
if (m_peer != mat) {
QChangeArbiter *arbiter = m_renderer->rendererAspect()->aspectManager()->changeArbiter();
- if (m_peer)
+ if (m_peer) {
+ m_parameterPack.clear();
arbiter->unregisterObserver(this, m_peer);
+ }
m_peer = mat;
// Register for changes
if (m_peer) {
arbiter->registerObserver(this, m_peer, ComponentUpdated);
- m_parameterPack.clear();
Q_FOREACH (QParameter *p, m_peer->parameters()) {
m_parameterPack.appendParameter(p);
}
@@ -130,7 +138,7 @@ void RenderMaterial::sceneChangeEvent(const QSceneChangePtr &e)
}
break;
}
- // Check for shader parameter
+ // Check for shader parameter
case ComponentAdded: {
QParameter *param = Q_NULLPTR;
if (propertyChange->propertyName() == QByteArrayLiteral("parameter") &&
diff --git a/src/render/backend/rendermaterial.h b/src/render/backend/rendermaterial.h
index d336a0ad5..1d36d6267 100644
--- a/src/render/backend/rendermaterial.h
+++ b/src/render/backend/rendermaterial.h
@@ -68,6 +68,7 @@ class RenderMaterial : public QObserverInterface
public:
RenderMaterial();
~RenderMaterial();
+ void cleanup();
void setPeer(QMaterial* mat);
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/rendermesh.cpp b/src/render/backend/rendermesh.cpp
index e8df82659..099f5fb40 100644
--- a/src/render/backend/rendermesh.cpp
+++ b/src/render/backend/rendermesh.cpp
@@ -85,6 +85,11 @@ RenderMesh::RenderMesh() :
RenderMesh::~RenderMesh()
{
+ cleanup();
+}
+
+void RenderMesh::cleanup()
+{
if (m_peer)
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
}
diff --git a/src/render/backend/rendermesh.h b/src/render/backend/rendermesh.h
index 86521f7e6..25779531a 100644
--- a/src/render/backend/rendermesh.h
+++ b/src/render/backend/rendermesh.h
@@ -74,6 +74,7 @@ class RenderMesh : public QObserverInterface
public:
RenderMesh();
~RenderMesh();
+ void cleanup();
void setPeer(QAbstractMesh *peer);
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/renderpassmanager.h b/src/render/backend/renderpassmanager.h
index 3ce69140a..ec92e518c 100644
--- a/src/render/backend/renderpassmanager.h
+++ b/src/render/backend/renderpassmanager.h
@@ -63,10 +63,13 @@ class RenderPassManager : public QResourcesManager<RenderRenderPass,
{
public:
RenderPassManager();
+
};
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderRenderPass, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE
diff --git a/src/render/backend/renderrenderpass.cpp b/src/render/backend/renderrenderpass.cpp
index e05489c56..6f892f136 100644
--- a/src/render/backend/renderrenderpass.cpp
+++ b/src/render/backend/renderrenderpass.cpp
@@ -61,6 +61,17 @@ RenderRenderPass::RenderRenderPass()
{
}
+RenderRenderPass::~RenderRenderPass()
+{
+ cleanup();
+}
+
+void RenderRenderPass::cleanup()
+{
+ if (m_renderer != Q_NULLPTR && m_peer != Q_NULLPTR)
+ m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
+}
+
void RenderRenderPass::setRenderer(Renderer *renderer)
{
m_renderer = renderer;
diff --git a/src/render/backend/renderrenderpass.h b/src/render/backend/renderrenderpass.h
index 13bf2907d..0e3a5384d 100644
--- a/src/render/backend/renderrenderpass.h
+++ b/src/render/backend/renderrenderpass.h
@@ -61,6 +61,8 @@ class RenderRenderPass : public QObserverInterface
{
public:
RenderRenderPass();
+ ~RenderRenderPass();
+ void cleanup();
void setRenderer(Renderer *renderer);
void setPeer(QRenderPass *peer);
diff --git a/src/render/backend/rendertechnique.cpp b/src/render/backend/rendertechnique.cpp
index be714ec26..1a1e431b1 100644
--- a/src/render/backend/rendertechnique.cpp
+++ b/src/render/backend/rendertechnique.cpp
@@ -66,6 +66,11 @@ RenderTechnique::RenderTechnique() :
RenderTechnique::~RenderTechnique()
{
+ cleanup();
+}
+
+void RenderTechnique::cleanup()
+{
if (m_renderer != Q_NULLPTR && m_peer != Q_NULLPTR)
m_renderer->rendererAspect()->aspectManager()->changeArbiter()->unregisterObserver(this, m_peer);
}
diff --git a/src/render/backend/rendertechnique.h b/src/render/backend/rendertechnique.h
index 1b9c85637..07bafd962 100644
--- a/src/render/backend/rendertechnique.h
+++ b/src/render/backend/rendertechnique.h
@@ -66,6 +66,7 @@ class RenderTechnique : public QObserverInterface
public:
RenderTechnique();
~RenderTechnique();
+ void cleanup();
void setRenderer(Renderer *renderer);
diff --git a/src/render/backend/techniquemanager.h b/src/render/backend/techniquemanager.h
index 63d46e7ec..1123b970d 100644
--- a/src/render/backend/techniquemanager.h
+++ b/src/render/backend/techniquemanager.h
@@ -68,6 +68,8 @@ public:
} // Render
+Q_DECLARE_RESOURCE_INFO(Render::RenderTechnique, Q_REQUIRES_CLEANUP);
+
} // Qt3D
QT_END_NAMESPACE