From a998e49b3455c9e28d2ed85f024f28c69921cfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Mon, 19 May 2014 08:39:47 +0300 Subject: Optimized custom item addition/removal Task-number: QTRD-3056 Change-Id: I653d8aeec797b76c19d9b542391b79e9370e7501 Reviewed-by: Miikka Heikkinen --- src/datavisualization/data/customrenderitem_p.h | 20 ++++++---- src/datavisualization/data/qcustom3ditem.cpp | 10 +++++ src/datavisualization/data/qcustom3ditem_p.h | 1 + .../engine/abstract3dcontroller.cpp | 4 +- .../engine/abstract3drenderer.cpp | 46 +++++++++++++--------- .../engine/abstract3drenderer_p.h | 2 +- 6 files changed, 55 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/datavisualization/data/customrenderitem_p.h b/src/datavisualization/data/customrenderitem_p.h index 3bf8067e..1722163b 100644 --- a/src/datavisualization/data/customrenderitem_p.h +++ b/src/datavisualization/data/customrenderitem_p.h @@ -44,17 +44,21 @@ public: virtual ~CustomRenderItem(); inline void setTexture(GLuint texture) { m_texture = texture; } - inline GLuint texture() { return m_texture; } + inline GLuint texture() const { return m_texture; } void setMesh(const QString &meshFile); - inline ObjectHelper *mesh() { return m_object; } + inline ObjectHelper *mesh() const { return m_object; } inline void setScaling(const QVector3D &scaling) { m_scaling = scaling; } - inline QVector3D scaling() { return m_scaling; } + inline QVector3D scaling() const { return m_scaling; } inline void setBlendNeeded(bool blend) { m_needBlend = blend; } - inline bool isBlendNeeded() { return m_needBlend; } + inline bool isBlendNeeded() const { return m_needBlend; } inline void setVisible(bool visible) { m_visible = visible; } - inline bool isVisible() { return m_visible; } + inline bool isVisible() const { return m_visible; } inline void setItemPointer(QCustom3DItem *item) { m_item = item; } - inline QCustom3DItem *itemPointer() { return m_item; } + inline QCustom3DItem *itemPointer() const { return m_item; } + inline void setValid(bool valid) { m_valid = valid; } + inline bool isValid() const { return m_valid; } + inline void setIndex(int index) { m_index = index; } + inline int index() const { return m_index; } private: GLuint m_texture; @@ -62,9 +66,11 @@ private: ObjectHelper *m_object; bool m_needBlend; bool m_visible; + bool m_valid; + int m_index; QCustom3DItem *m_item; }; -typedef QVector CustomRenderItemArray; +typedef QHash CustomRenderItemArray; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp index ca4cef16..bb6c96eb 100644 --- a/src/datavisualization/data/qcustom3ditem.cpp +++ b/src/datavisualization/data/qcustom3ditem.cpp @@ -310,4 +310,14 @@ void QCustom3DItemPrivate::clearTextureImage() m_textureImage = QImage(); } +void QCustom3DItemPrivate::resetDirtyBits() +{ + m_dirtyBits.textureDirty = false; + m_dirtyBits.meshDirty = false; + m_dirtyBits.positionDirty = false; + m_dirtyBits.scalingDirty = false; + m_dirtyBits.rotationDirty = false; + m_dirtyBits.visibleDirty = false; +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/data/qcustom3ditem_p.h b/src/datavisualization/data/qcustom3ditem_p.h index 89f47501..007c9fc4 100644 --- a/src/datavisualization/data/qcustom3ditem_p.h +++ b/src/datavisualization/data/qcustom3ditem_p.h @@ -63,6 +63,7 @@ public: QImage textureImage(); void clearTextureImage(); + void resetDirtyBits(); public: QCustom3DItem *q_ptr; diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 473ad34c..98fff81e 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -884,6 +884,7 @@ int Abstract3DController::addCustomItem(QCustom3DItem *item) connect(item->d_ptr.data(), &QCustom3DItemPrivate::needUpdate, this, &Abstract3DController::updateCustomItem); m_customItems.append(item); + item->d_ptr->resetDirtyBits(); m_isCustomDataDirty = true; emitNeedRender(); return m_customItems.count() - 1; @@ -914,9 +915,8 @@ void Abstract3DController::deleteCustomItem(const QVector3D &position) { // Get the item for the position foreach (QCustom3DItem *item, m_customItems) { - if (item->position() == position) { + if (item->position() == position) deleteCustomItem(item); - } } } diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 920b8cf0..06954165 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -416,21 +416,34 @@ void Abstract3DRenderer::updateCustomData(const QList &customIt if (customItems.isEmpty() && m_customRenderCache.isEmpty()) return; - // There are probably not too many custom items, just recreate the array if something changes - foreach (CustomRenderItem *item, m_customRenderCache) { - GLuint texture = item->texture(); - m_textureHelper->deleteTexture(&texture); - delete item; + foreach (CustomRenderItem *item, m_customRenderCache) + item->setValid(false); + + int itemCount = customItems.size(); + // Check custom item list for items that are not yet in render item cache + for (int i = 0; i < itemCount; i++) { + QCustom3DItem *item = customItems.at(i); + CustomRenderItem *renderItem = m_customRenderCache.value(item); + if (!renderItem) + renderItem = addCustomItem(item); + renderItem->setValid(true); + renderItem->setIndex(i); // always update index, as it must match the custom item index + } + + // Check render item cache and remove items that are not in customItems list anymore + foreach (CustomRenderItem *renderItem, m_customRenderCache) { + if (!renderItem->isValid()) { + m_customRenderCache.remove(renderItem->itemPointer()); + GLuint texture = renderItem->texture(); + m_textureHelper->deleteTexture(&texture); + delete renderItem; + } } - m_customRenderCache.clear(); - foreach (QCustom3DItem *item, customItems) - addCustomItem(item); } void Abstract3DRenderer::updateCustomItems() { // Check all items - // TODO: Call updateCustomItem in a loop, as we can probably utilize the same function in updateCustomData when doing QTRD-3056 foreach (CustomRenderItem *item, m_customRenderCache) updateCustomItem(item); } @@ -546,7 +559,7 @@ QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index) return QVector4D(idxRed, idxGreen, idxBlue, 0); } -void Abstract3DRenderer::addCustomItem(QCustom3DItem *item) +CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item) { CustomRenderItem *newItem = new CustomRenderItem(); newItem->setItemPointer(item); // Store pointer for render item updates @@ -557,12 +570,12 @@ void Abstract3DRenderer::addCustomItem(QCustom3DItem *item) newItem->setBlendNeeded(textureImage.hasAlphaChannel()); GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true); newItem->setTexture(texture); - // TODO: Uncomment this once custom item render cache handling has been optimized (QTRD-3056) - //item->d_ptr->clearTextureImage(); + item->d_ptr->clearTextureImage(); QVector3D translation = convertPositionToTranslation(item->position()); newItem->setTranslation(translation); newItem->setVisible(item->isVisible()); - m_customRenderCache.append(newItem); + m_customRenderCache.insert(item, newItem); + return newItem; } void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem) @@ -587,8 +600,7 @@ void Abstract3DRenderer::updateCustomItem(CustomRenderItem *renderItem) m_textureHelper->deleteTexture(&oldTexture); GLuint texture = m_textureHelper->create2DTexture(textureImage, true, true, true); renderItem->setTexture(texture); - // TODO: Uncomment this once custom item render cache handling has been optimized (QTRD-3056) - //item->d_ptr->clearTextureImage(); + item->d_ptr->clearTextureImage(); item->d_ptr->m_dirtyBits.textureDirty = false; } if (item->d_ptr->m_dirtyBits.positionDirty) { @@ -613,8 +625,6 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state, if (m_customRenderCache.isEmpty()) return; - int itemIndex = 0; - if (RenderingNormal == state) { shader->bind(); shader->setUniformValue(shader->lightP(), m_cachedScene->activeLight()->position()); @@ -677,7 +687,7 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state, } else if (RenderingSelection == state) { // Selection render shader->setUniformValue(shader->MVP(), MVPMatrix); - QVector4D itemColor = indexToSelectionColor(itemIndex++); + QVector4D itemColor = indexToSelectionColor(item->index()); itemColor.setW(customItemAlpha); itemColor /= 255.0f; shader->setUniformValue(shader->color(), itemColor); diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 949ba104..5cfb88ae 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -112,7 +112,7 @@ public: virtual void fixMeshFileName(QString &fileName, QAbstract3DSeries::Mesh mesh); - virtual void addCustomItem(QCustom3DItem *item); + virtual CustomRenderItem *addCustomItem(QCustom3DItem *item); virtual void updateCustomItem(CustomRenderItem *renderItem); virtual QVector3D convertPositionToTranslation(const QVector3D &position) = 0; -- cgit v1.2.3