From cb79f11be1c0c379a1eccea62606a58b73442f2f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Wed, 21 May 2014 13:37:11 +0300 Subject: Cache ObjectHelper instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTRD-2792 Change-Id: I90d83bd9b73a0f337fd26f1b92000e72b3ec0607 Reviewed-by: Tomi Korpipää --- src/datavisualization/data/customrenderitem.cpp | 18 ++--- src/datavisualization/data/customrenderitem_p.h | 9 ++- .../engine/abstract3drenderer.cpp | 1 + src/datavisualization/engine/bars3drenderer.cpp | 24 +++---- src/datavisualization/engine/bars3drenderer_p.h | 6 +- src/datavisualization/engine/scatter3drenderer.cpp | 24 +++---- src/datavisualization/engine/scatter3drenderer_p.h | 6 +- src/datavisualization/engine/selectionpointer.cpp | 15 ++--- src/datavisualization/engine/selectionpointer_p.h | 4 +- src/datavisualization/engine/seriesrendercache.cpp | 10 +-- src/datavisualization/engine/seriesrendercache_p.h | 2 +- src/datavisualization/engine/surface3drenderer.cpp | 26 ++++---- src/datavisualization/engine/surface3drenderer_p.h | 6 +- src/datavisualization/utils/objecthelper.cpp | 76 +++++++++++++++++++++- src/datavisualization/utils/objecthelper_p.h | 15 ++++- 15 files changed, 146 insertions(+), 96 deletions(-) (limited to 'src') diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp index 53db9bd1..a1c70057 100644 --- a/src/datavisualization/data/customrenderitem.cpp +++ b/src/datavisualization/data/customrenderitem.cpp @@ -24,29 +24,19 @@ CustomRenderItem::CustomRenderItem() : AbstractRenderItem(), m_texture(0), m_object(0), - m_visible(true) + m_visible(true), + m_renderer(0) { } -CustomRenderItem::CustomRenderItem(const CustomRenderItem &other) - : AbstractRenderItem(other) -{ - m_texture = other.m_texture; -} - CustomRenderItem::~CustomRenderItem() { - if (m_object) - delete m_object; + ObjectHelper::releaseObjectHelper(m_renderer, m_object); } void CustomRenderItem::setMesh(const QString &meshFile) { - if (m_object) - delete m_object; - // Load mesh and make an object of it - m_object = new ObjectHelper(meshFile); - m_object->load(); + ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFile); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h index f05540d0..17195f7b 100644 --- a/src/datavisualization/data/customrenderitem_p.h +++ b/src/datavisualization/data/customrenderitem_p.h @@ -35,12 +35,12 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION class QCustom3DItem; +class Abstract3DRenderer; class CustomRenderItem : public AbstractRenderItem { public: CustomRenderItem(); - CustomRenderItem(const CustomRenderItem &other); virtual ~CustomRenderItem(); inline void setTexture(GLuint texture) { m_texture = texture; } @@ -65,19 +65,24 @@ public: inline int index() const { return m_index; } inline void setShadowCasting(bool shadowCasting) { m_shadowCasting = shadowCasting; } inline bool isShadowCasting() const { return m_shadowCasting; } + inline void setRenderer(Abstract3DRenderer *renderer) { m_renderer = renderer; } private: + Q_DISABLE_COPY(CustomRenderItem) + GLuint m_texture; QVector3D m_scaling; QVector3D m_position; bool m_absolute; - ObjectHelper *m_object; + ObjectHelper *m_object; // shared reference bool m_needBlend; bool m_visible; bool m_valid; int m_index; bool m_shadowCasting; QCustom3DItem *m_item; + Abstract3DRenderer *m_renderer; + }; typedef QHash CustomRenderItemArray; diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 988ea21e..8c2e9578 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -570,6 +570,7 @@ QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index) CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item) { CustomRenderItem *newItem = new CustomRenderItem(); + newItem->setRenderer(this); newItem->setItemPointer(item); // Store pointer for render item updates newItem->setMesh(item->meshFile()); newItem->setScaling(item->scaling()); diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index 4dcf296f..ec13525b 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -120,9 +120,9 @@ Bars3DRenderer::~Bars3DRenderer() delete m_depthShader; delete m_selectionShader; delete m_backgroundShader; - delete m_backgroundObj; - delete m_gridLineObj; - delete m_labelObj; + ObjectHelper::releaseObjectHelper(this, m_backgroundObj); + ObjectHelper::releaseObjectHelper(this, m_gridLineObj); + ObjectHelper::releaseObjectHelper(this, m_labelObj); delete m_labelShader; } @@ -2336,26 +2336,20 @@ void Bars3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality void Bars3DRenderer::loadBackgroundMesh() { - if (m_backgroundObj) - delete m_backgroundObj; - m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground")); - m_backgroundObj->load(); + ObjectHelper::resetObjectHelper(this, m_backgroundObj, + QStringLiteral(":/defaultMeshes/negativeBackground")); } void Bars3DRenderer::loadGridLineMesh() { - if (m_gridLineObj) - delete m_gridLineObj; - m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_gridLineObj->load(); + ObjectHelper::resetObjectHelper(this, m_gridLineObj, + QStringLiteral(":/defaultMeshes/plane")); } void Bars3DRenderer::loadLabelMesh() { - if (m_labelObj) - delete m_labelObj; - m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_labelObj->load(); + ObjectHelper::resetObjectHelper(this, m_labelObj, + QStringLiteral(":/defaultMeshes/plane")); } void Bars3DRenderer::updateTextures() diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 2e9ec0de..d62171eb 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -73,9 +73,9 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_backgroundObj; - ObjectHelper *m_gridLineObj; - ObjectHelper *m_labelObj; + ObjectHelper *m_backgroundObj; // Shared reference + ObjectHelper *m_gridLineObj; // Shared reference + ObjectHelper *m_labelObj; // Shared reference GLuint m_bgrTexture; GLuint m_depthTexture; GLuint m_selectionTexture; diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index acdd3cb8..3c1adfa0 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -118,11 +118,11 @@ Scatter3DRenderer::~Scatter3DRenderer() delete m_selectionShader; delete m_backgroundShader; delete m_labelShader; - delete m_backgroundObj; + ObjectHelper::releaseObjectHelper(this, m_backgroundObj); #if !defined(QT_OPENGL_ES_2) - delete m_gridLineObj; + ObjectHelper::releaseObjectHelper(this, m_gridLineObj); #endif - delete m_labelObj; + ObjectHelper::releaseObjectHelper(this, m_labelObj); } void Scatter3DRenderer::initializeOpenGL() @@ -1731,28 +1731,22 @@ void Scatter3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality qual void Scatter3DRenderer::loadBackgroundMesh() { - if (m_backgroundObj) - delete m_backgroundObj; - m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background")); - m_backgroundObj->load(); + ObjectHelper::resetObjectHelper(this, m_backgroundObj, + QStringLiteral(":/defaultMeshes/background")); } #if !(defined QT_OPENGL_ES_2) void Scatter3DRenderer::loadGridLineMesh() { - if (m_gridLineObj) - delete m_gridLineObj; - m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_gridLineObj->load(); + ObjectHelper::resetObjectHelper(this, m_gridLineObj, + QStringLiteral(":/defaultMeshes/plane")); } #endif void Scatter3DRenderer::loadLabelMesh() { - if (m_labelObj) - delete m_labelObj; - m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_labelObj->load(); + ObjectHelper::resetObjectHelper(this, m_labelObj, + QStringLiteral(":/defaultMeshes/plane")); } void Scatter3DRenderer::updateTextures() diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 0b58102b..b6a110ff 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -68,11 +68,11 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; - ObjectHelper *m_backgroundObj; + ObjectHelper *m_backgroundObj; // Shared reference #if !(defined QT_OPENGL_ES_2) - ObjectHelper *m_gridLineObj; + ObjectHelper *m_gridLineObj; // Shared reference #endif - ObjectHelper *m_labelObj; + ObjectHelper *m_labelObj; // Shared reference GLuint m_bgrTexture; GLuint m_depthTexture; GLuint m_selectionTexture; diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp index 646212f0..fe9325cf 100644 --- a/src/datavisualization/engine/selectionpointer.cpp +++ b/src/datavisualization/engine/selectionpointer.cpp @@ -54,7 +54,6 @@ SelectionPointer::~SelectionPointer() { delete m_labelShader; delete m_pointShader; - delete m_labelObj; delete m_textureHelper; } @@ -66,7 +65,6 @@ void SelectionPointer::initializeOpenGL() m_drawer->initializeOpenGL(); initShaders(); - loadLabelMesh(); } void SelectionPointer::updateScene(Q3DScene *scene) @@ -235,6 +233,11 @@ void SelectionPointer::setPointerObject(ObjectHelper *object) m_pointObj = object; } +void SelectionPointer::setLabelObject(ObjectHelper *object) +{ + m_labelObj = object; +} + void SelectionPointer::handleDrawerChange() { m_cachedTheme = m_drawer->theme(); @@ -269,12 +272,4 @@ void SelectionPointer::initShaders() } -void SelectionPointer::loadLabelMesh() -{ - if (m_labelObj) - delete m_labelObj; - m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_labelObj->load(); -} - QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/selectionpointer_p.h b/src/datavisualization/engine/selectionpointer_p.h index 03e09cca..f33cd6cd 100644 --- a/src/datavisualization/engine/selectionpointer_p.h +++ b/src/datavisualization/engine/selectionpointer_p.h @@ -53,6 +53,7 @@ public: void setPosition(const QVector3D &position); void setLabel(const QString &label); void setPointerObject(ObjectHelper *object); + void setLabelObject(ObjectHelper *object); void handleDrawerChange(); void updateBoundingRect(const QRect &rect); void updateScene(Q3DScene *scene); @@ -63,12 +64,11 @@ public: private: void initializeOpenGL(); void initShaders(); - void loadLabelMesh(); private: ShaderHelper *m_labelShader; ShaderHelper *m_pointShader; - ObjectHelper *m_labelObj; + ObjectHelper *m_labelObj; // Not owned ObjectHelper *m_pointObj; // Not owned TextureHelper *m_textureHelper; Q3DTheme *m_cachedTheme; diff --git a/src/datavisualization/engine/seriesrendercache.cpp b/src/datavisualization/engine/seriesrendercache.cpp index e674ae43..e4f221f8 100644 --- a/src/datavisualization/engine/seriesrendercache.cpp +++ b/src/datavisualization/engine/seriesrendercache.cpp @@ -109,13 +109,7 @@ void SeriesRenderCache::populate(bool newSeries) m_renderer->fixMeshFileName(meshFileName, m_mesh); } - delete m_object; - if (meshFileName.isEmpty()) { - m_object = 0; - } else { - m_object = new ObjectHelper(meshFileName); - m_object->load(); - } + ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFileName); } if (newSeries || changeTracker.meshRotationChanged) { @@ -193,7 +187,7 @@ void SeriesRenderCache::populate(bool newSeries) void SeriesRenderCache::cleanup(TextureHelper *texHelper) { - delete m_object; + ObjectHelper::releaseObjectHelper(m_renderer, m_object); if (QOpenGLContext::currentContext()) { texHelper->deleteTexture(&m_baseUniformTexture); texHelper->deleteTexture(&m_baseGradientTexture); diff --git a/src/datavisualization/engine/seriesrendercache_p.h b/src/datavisualization/engine/seriesrendercache_p.h index 3cd94487..96b61b87 100644 --- a/src/datavisualization/engine/seriesrendercache_p.h +++ b/src/datavisualization/engine/seriesrendercache_p.h @@ -74,7 +74,7 @@ public: protected: QAbstract3DSeries *m_series; - ObjectHelper *m_object; + ObjectHelper *m_object; // Shared reference QAbstract3DSeries::Mesh m_mesh; QQuaternion m_meshRotation; diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 4b5464d5..1f3a6932 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -142,11 +142,11 @@ Surface3DRenderer::~Surface3DRenderer() delete m_surfaceSliceSmoothShader; delete m_labelShader; - delete m_backgroundObj; + ObjectHelper::releaseObjectHelper(this, m_backgroundObj); #if !defined(QT_OPENGL_ES_2) - delete m_gridLineObj; + ObjectHelper::releaseObjectHelper(this, m_gridLineObj); #endif - delete m_labelObj; + ObjectHelper::releaseObjectHelper(this, m_labelObj); } void Surface3DRenderer::initializeOpenGL() @@ -2311,19 +2311,15 @@ void Surface3DRenderer::resetClickedStatus() void Surface3DRenderer::loadBackgroundMesh() { - if (m_backgroundObj) - delete m_backgroundObj; - m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background")); - m_backgroundObj->load(); + ObjectHelper::resetObjectHelper(this, m_backgroundObj, + QStringLiteral(":/defaultMeshes/background")); } #if !(defined QT_OPENGL_ES_2) void Surface3DRenderer::loadGridLineMesh() { - if (m_gridLineObj) - delete m_gridLineObj; - m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_gridLineObj->load(); + ObjectHelper::resetObjectHelper(this, m_gridLineObj, + QStringLiteral(":/defaultMeshes/plane")); } #endif @@ -2407,6 +2403,7 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co slicePointer->setPosition((subPosFront + subPosBack) / 2.0f); slicePointer->setLabel(selectionLabel); slicePointer->setPointerObject(cache->object()); + slicePointer->setLabelObject(m_labelObj); slicePointer->setHighlightColor(cache->singleHighlightColor()); slicePointer->updateScene(m_cachedScene); slicePointer->setRotation(cache->meshRotation()); @@ -2420,6 +2417,7 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co mainPointer->setPosition(mainPos); mainPointer->setLabel(selectionLabel); mainPointer->setPointerObject(cache->object()); + mainPointer->setLabelObject(m_labelObj); mainPointer->setHighlightColor(cache->singleHighlightColor()); mainPointer->updateScene(m_cachedScene); mainPointer->setRotation(cache->meshRotation()); @@ -2548,10 +2546,8 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing) void Surface3DRenderer::loadLabelMesh() { - if (m_labelObj) - delete m_labelObj; - m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane")); - m_labelObj->load(); + ObjectHelper::resetObjectHelper(this, m_labelObj, + QStringLiteral(":/defaultMeshes/plane")); } void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader) diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index 7c3e461d..e6c66a90 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -73,11 +73,11 @@ private: GLfloat m_maxVisibleRowValue; GLfloat m_visibleColumnRange; GLfloat m_visibleRowRange; - ObjectHelper *m_backgroundObj; + ObjectHelper *m_backgroundObj; // Shared reference #if !(defined QT_OPENGL_ES_2) - ObjectHelper *m_gridLineObj; + ObjectHelper *m_gridLineObj; // Shared reference #endif - ObjectHelper *m_labelObj; + ObjectHelper *m_labelObj; // Shared reference GLuint m_depthTexture; GLuint m_depthModelTexture; GLuint m_depthFrameBuffer; diff --git a/src/datavisualization/utils/objecthelper.cpp b/src/datavisualization/utils/objecthelper.cpp index 97695193..8cbf2aa2 100644 --- a/src/datavisualization/utils/objecthelper.cpp +++ b/src/datavisualization/utils/objecthelper.cpp @@ -27,15 +27,87 @@ ObjectHelper::ObjectHelper(const QString &objectFile) : m_objectFile(objectFile) { m_indicesType = GL_UNSIGNED_SHORT; + load(); } +struct ObjectHelperRef { + int refCount; + ObjectHelper *obj; +}; + +// The "Abstract3DRenderer *" key identifies the renderer +static QHash *> cacheTable; + ObjectHelper::~ObjectHelper() { } -void ObjectHelper::setObjectFile(const QString &objectFile) +void ObjectHelper::resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj, + const QString &meshFile) +{ + Q_ASSERT(cacheId); + + if (obj) { + const QString &oldFile = obj->objectFile(); + if (meshFile == oldFile) + return; // same file, do nothing + releaseObjectHelper(cacheId, obj); + } + obj = getObjectHelper(cacheId, meshFile); +} + +void ObjectHelper::releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj) +{ + Q_ASSERT(cacheId); + + if (obj) { + QHash *objectTable = cacheTable.value(cacheId, 0); + if (objectTable) { + // Delete object if last reference is released + ObjectHelperRef *objRef = objectTable->value(obj->m_objectFile, 0); + if (objRef) { + objRef->refCount--; + if (objRef->refCount <= 0) { + objectTable->remove(obj->m_objectFile); + delete objRef->obj; + delete objRef; + } + } + if (objectTable->isEmpty()) { + // Remove the entire cache if last object was removed + cacheTable.remove(cacheId); + delete objectTable; + } + } else { + // Just delete the object if unknown cache + delete obj; + } + obj = 0; + } +} + +ObjectHelper *ObjectHelper::getObjectHelper(const Abstract3DRenderer *cacheId, + const QString &objectFile) { - m_objectFile = objectFile; + if (objectFile.isEmpty()) + return 0; + + QHash *objectTable = cacheTable.value(cacheId, 0); + if (!objectTable) { + objectTable = new QHash; + cacheTable.insert(cacheId, objectTable); + } + + // Check if object helper for this mesh already exists + ObjectHelperRef *objRef = objectTable->value(objectFile, 0); + if (!objRef) { + objRef = new ObjectHelperRef; + objRef->refCount = 0; + objRef->obj = new ObjectHelper(objectFile); + objectTable->insert(objectFile, objRef); + } + objRef->refCount++; + return objRef->obj; } void ObjectHelper::load() diff --git a/src/datavisualization/utils/objecthelper_p.h b/src/datavisualization/utils/objecthelper_p.h index 0260dd05..93dc6c94 100644 --- a/src/datavisualization/utils/objecthelper_p.h +++ b/src/datavisualization/utils/objecthelper_p.h @@ -35,17 +35,26 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION +class Abstract3DRenderer; + class ObjectHelper : public AbstractObjectHelper { +private: + ObjectHelper(const QString &objectFile); public: - ObjectHelper(const QString &objectFile = QString()); ~ObjectHelper(); - void setObjectFile(const QString &objectFile); + static void resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj, + const QString &meshFile); + static void releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj); - void load(); + inline const QString &objectFile() { return m_objectFile; } private: + static ObjectHelper *getObjectHelper(const Abstract3DRenderer *cacheId, + const QString &objectFile); + void load(); + QString m_objectFile; }; -- cgit v1.2.3