diff options
author | Mike Krus <mike.krus@kdab.com> | 2019-10-03 15:50:42 +0100 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2019-10-08 15:27:03 +0100 |
commit | d3507c90e20a8f2b0a78428a3c78888dbe2138d9 (patch) | |
tree | 2e95f525b4f2003bd38fcad3dcf4df58b721815b | |
parent | bf437f7da6c57307f93a24162981d4efd989fc53 (diff) |
Update UpdateLevelOfDetailJob to use direct sync
Change-Id: I26ca21fc0f18bc79f3554824869eefc2178e83f8
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r-- | src/render/backend/levelofdetail.cpp | 9 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetail.cpp | 29 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetail.h | 1 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetail_p.h | 2 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetailswitch.cpp | 65 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetailswitch.h | 4 | ||||
-rw-r--r-- | src/render/frontend/qlevelofdetailswitch_p.h | 77 | ||||
-rw-r--r-- | src/render/frontend/render-frontend.pri | 1 | ||||
-rw-r--r-- | src/render/jobs/updatelevelofdetailjob.cpp | 46 | ||||
-rw-r--r-- | src/render/jobs/updatelevelofdetailjob_p.h | 3 |
10 files changed, 168 insertions, 69 deletions
diff --git a/src/render/backend/levelofdetail.cpp b/src/render/backend/levelofdetail.cpp index 08410edf9..7f528a9d5 100644 --- a/src/render/backend/levelofdetail.cpp +++ b/src/render/backend/levelofdetail.cpp @@ -41,7 +41,6 @@ #include <Qt3DRender/QLevelOfDetail> #include <Qt3DRender/private/qlevelofdetail_p.h> #include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DRender/QCamera> #include <QVariant> @@ -111,14 +110,8 @@ void LevelOfDetail::cleanup() void LevelOfDetail::setCurrentIndex(int currentIndex) { - if (m_currentIndex != currentIndex) { + if (m_currentIndex != currentIndex) m_currentIndex = currentIndex; - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); - e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); - e->setPropertyName("currentIndex"); - e->setValue(m_currentIndex); - notifyObservers(e); - } } } // namespace Render diff --git a/src/render/frontend/qlevelofdetail.cpp b/src/render/frontend/qlevelofdetail.cpp index a3596a518..3d0cb9553 100644 --- a/src/render/frontend/qlevelofdetail.cpp +++ b/src/render/frontend/qlevelofdetail.cpp @@ -40,7 +40,6 @@ #include "qlevelofdetail.h" #include "qlevelofdetail_p.h" #include "qcamera.h" -#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -55,6 +54,15 @@ QLevelOfDetailPrivate::QLevelOfDetailPrivate() { } +void QLevelOfDetailPrivate::setCurrentIndex(int currentIndex) +{ + Q_Q(QLevelOfDetail); + if (m_currentIndex != currentIndex) { + m_currentIndex = currentIndex; + emit q->currentIndexChanged(m_currentIndex); + } +} + /*! \class Qt3DRender::QLevelOfDetail \inmodule Qt3DRender @@ -317,20 +325,6 @@ Qt3DCore::QNodeCreatedChangeBasePtr QLevelOfDetail::createNodeCreationChange() c return creationChange; } -/*! \internal */ -void QLevelOfDetail::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) -{ - Q_D(QLevelOfDetail); - Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); - if (e->type() == Qt3DCore::PropertyUpdated) { - if (e->propertyName() == QByteArrayLiteral("currentIndex")) { - int ndx = e->value().value<int>(); - d->m_currentIndex = ndx; - emit currentIndexChanged(ndx); - } - } -} - QCamera *QLevelOfDetail::camera() const { Q_D(const QLevelOfDetail); @@ -367,10 +361,7 @@ int QLevelOfDetail::currentIndex() const void QLevelOfDetail::setCurrentIndex(int currentIndex) { Q_D(QLevelOfDetail); - if (d->m_currentIndex != currentIndex) { - d->m_currentIndex = currentIndex; - emit currentIndexChanged(d->m_currentIndex); - } + d->setCurrentIndex(currentIndex); } QLevelOfDetail::ThresholdType QLevelOfDetail::thresholdType() const diff --git a/src/render/frontend/qlevelofdetail.h b/src/render/frontend/qlevelofdetail.h index 308a4d3c0..f6c09a287 100644 --- a/src/render/frontend/qlevelofdetail.h +++ b/src/render/frontend/qlevelofdetail.h @@ -97,7 +97,6 @@ Q_SIGNALS: protected: explicit QLevelOfDetail(QLevelOfDetailPrivate &dd, Qt3DCore::QNode *parent = nullptr); Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: Q_DECLARE_PRIVATE(QLevelOfDetail) diff --git a/src/render/frontend/qlevelofdetail_p.h b/src/render/frontend/qlevelofdetail_p.h index 7b409e4ca..429128427 100644 --- a/src/render/frontend/qlevelofdetail_p.h +++ b/src/render/frontend/qlevelofdetail_p.h @@ -72,6 +72,8 @@ public: void _q_radiusChanged(float radius); void _q_centerChanged(const QVector3D ¢er); + virtual void setCurrentIndex(int currentIndex); + QCamera *m_camera; int m_currentIndex; QLevelOfDetail::ThresholdType m_thresholdType; diff --git a/src/render/frontend/qlevelofdetailswitch.cpp b/src/render/frontend/qlevelofdetailswitch.cpp index 845fdd5a6..7b888fe98 100644 --- a/src/render/frontend/qlevelofdetailswitch.cpp +++ b/src/render/frontend/qlevelofdetailswitch.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qlevelofdetailswitch.h" +#include "qlevelofdetailswitch_p.h" #include "qlevelofdetail_p.h" #include "qglobal.h" #include <Qt3DCore/QEntity> @@ -47,6 +48,38 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +QLevelOfDetailSwitchPrivate::QLevelOfDetailSwitchPrivate() + : QLevelOfDetailPrivate() +{ + +} + +void QLevelOfDetailSwitchPrivate::setCurrentIndex(int currentIndex) +{ + Q_Q(QLevelOfDetailSwitch); + + bool changed = m_currentIndex != currentIndex; + QLevelOfDetailPrivate::setCurrentIndex(currentIndex); + + if (!changed) + return; + + int entityIndex = 0; + const auto entities = q->entities(); + for (Qt3DCore::QEntity *entity : entities) { + const auto childNodes = entity->childNodes(); + for (Qt3DCore::QNode *childNode : childNodes) { + Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>(childNode); + if (childEntity) { + childEntity->setEnabled(entityIndex == currentIndex); + entityIndex++; + } + } + + break; // only work on the first entity, LOD should not be shared + } +} + /*! \class Qt3DRender::QLevelOfDetailSwitch \inmodule Qt3DRender @@ -84,9 +117,9 @@ namespace Qt3DRender { Constructs a new QLevelOfDetailSwitch with the specified \a parent. */ QLevelOfDetailSwitch::QLevelOfDetailSwitch(QNode *parent) - : QLevelOfDetail(parent) + : QLevelOfDetail(*new QLevelOfDetailSwitchPrivate(), parent) { - Q_D(QLevelOfDetail); + Q_D(QLevelOfDetailSwitch); d->m_currentIndex = -1; } @@ -101,34 +134,6 @@ QLevelOfDetailSwitch::QLevelOfDetailSwitch(QLevelOfDetailPrivate &dd, QNode *par { } -/*! \internal */ -void QLevelOfDetailSwitch::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) -{ - Q_D(QLevelOfDetail); - Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); - if (e->type() == Qt3DCore::PropertyUpdated) { - if (e->propertyName() == QByteArrayLiteral("currentIndex")) { - int ndx = e->value().value<int>(); - d->m_currentIndex = ndx; - emit currentIndexChanged(ndx); - - int entityIndex = 0; - const auto entities = this->entities(); - for (Qt3DCore::QEntity *entity : entities) { - const auto childNodes = entity->childNodes(); - for (Qt3DCore::QNode *childNode : childNodes) { - Qt3DCore::QEntity *childEntity = qobject_cast<Qt3DCore::QEntity *>(childNode); - if (childEntity) { - childEntity->setEnabled(entityIndex == ndx); - entityIndex++; - } - } - break; // only work on the first entity, LOD should not be shared - } - } - } -} - } // namespace Qt3DRender QT_END_NAMESPACE diff --git a/src/render/frontend/qlevelofdetailswitch.h b/src/render/frontend/qlevelofdetailswitch.h index 1615d16e6..90f4ee3e2 100644 --- a/src/render/frontend/qlevelofdetailswitch.h +++ b/src/render/frontend/qlevelofdetailswitch.h @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +class QLevelOfDetailSwitchPrivate; class Q_3DRENDERSHARED_EXPORT QLevelOfDetailSwitch : public QLevelOfDetail { @@ -56,10 +57,9 @@ public: protected: explicit QLevelOfDetailSwitch(QLevelOfDetailPrivate &dd, Qt3DCore::QNode *parent = nullptr); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: - Q_DECLARE_PRIVATE(QLevelOfDetail) + Q_DECLARE_PRIVATE(QLevelOfDetailSwitch) }; } // namespace Qt3DRender diff --git a/src/render/frontend/qlevelofdetailswitch_p.h b/src/render/frontend/qlevelofdetailswitch_p.h new file mode 100644 index 000000000..51321c986 --- /dev/null +++ b/src/render/frontend/qlevelofdetailswitch_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_QLEVELOFDETAILSWITCH_P_H +#define QT3DRENDER_QLEVELOFDETAILSWITCH_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qlevelofdetail_p.h> +#include <Qt3DRender/qlevelofdetailswitch.h> + +#include <QVector3D> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class Q_3DRENDERSHARED_PRIVATE_EXPORT QLevelOfDetailSwitchPrivate : public QLevelOfDetailPrivate +{ +public: + QLevelOfDetailSwitchPrivate(); + + Q_DECLARE_PUBLIC(QLevelOfDetailSwitch) + + void setCurrentIndex(int currentIndex) override; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QLEVELOFDETAILSWITCH_P_H diff --git a/src/render/frontend/render-frontend.pri b/src/render/frontend/render-frontend.pri index 1fafcc294..0153e9c97 100644 --- a/src/render/frontend/render-frontend.pri +++ b/src/render/frontend/render-frontend.pri @@ -9,6 +9,7 @@ HEADERS += \ $$PWD/qlevelofdetail.h \ $$PWD/qlevelofdetail_p.h \ $$PWD/qlevelofdetailswitch.h \ + $$PWD/qlevelofdetailswitch_p.h \ $$PWD/qrendertarget.h \ $$PWD/qrendertarget_p.h \ $$PWD/sphere_p.h \ diff --git a/src/render/jobs/updatelevelofdetailjob.cpp b/src/render/jobs/updatelevelofdetailjob.cpp index b5349a2c1..0a28b7628 100644 --- a/src/render/jobs/updatelevelofdetailjob.cpp +++ b/src/render/jobs/updatelevelofdetailjob.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "updatelevelofdetailjob_p.h" +#include <Qt3DCore/private/qaspectmanager_p.h> #include <Qt3DRender/QLevelOfDetail> #include <Qt3DRender/private/entityvisitor_p.h> #include <Qt3DRender/private/job_common_p.h> @@ -66,9 +67,11 @@ public: , m_filterValue(filterValue) , m_frameGraphRoot(frameGraphRoot) { + m_updatedIndices.reserve(manager->levelOfDetailManager()->count()); } double filterValue() const { return m_filterValue; } + const QVector<QPair<Qt3DCore::QNodeId, int>> &updatedIndices() const { return m_updatedIndices; } Operation visit(Qt3DRender::Render::Entity *entity = nullptr) override { using namespace Qt3DRender; @@ -102,6 +105,7 @@ public: private: double m_filterValue = 0.; Qt3DRender::Render::FrameGraphNode *m_frameGraphRoot; + QVector<QPair<Qt3DCore::QNodeId, int>> m_updatedIndices; void updateEntityLodByDistance(Qt3DRender::Render::Entity *entity, Qt3DRender::Render::LevelOfDetail *lod) { @@ -128,8 +132,10 @@ private: if (dist <= thresholds[i] || i == n -1) { m_filterValue = approxRollingAverage<30>(m_filterValue, i); i = qBound(0, static_cast<int>(qRound(m_filterValue)), n - 1); - if (lod->currentIndex() != i) + if (lod->currentIndex() != i) { lod->setCurrentIndex(i); + m_updatedIndices.push_back({lod->peerId(), i}); + } break; } } @@ -172,8 +178,10 @@ private: if (thresholds[i] < area || i == n -1) { m_filterValue = approxRollingAverage<30>(m_filterValue, i); i = qBound(0, static_cast<int>(qRound(m_filterValue)), n - 1); - if (lod->currentIndex() != i) + if (lod->currentIndex() != i) { lod->setCurrentIndex(i); + m_updatedIndices.push_back({lod->peerId(), i}); + } break; } } @@ -199,13 +207,24 @@ private: namespace Qt3DRender { namespace Render { +class UpdateLevelOfDetailJobPrivate : public Qt3DCore::QAspectJobPrivate +{ +public: + UpdateLevelOfDetailJobPrivate() { } + + void postFrame(Qt3DCore::QAspectManager *manager) override; + + QVector<QPair<Qt3DCore::QNodeId, int>> m_updatedIndices; +}; + UpdateLevelOfDetailJob::UpdateLevelOfDetailJob() - : m_manager(nullptr) + : Qt3DCore::QAspectJob(*new UpdateLevelOfDetailJobPrivate) + , m_manager(nullptr) , m_frameGraphRoot(nullptr) , m_root(nullptr) , m_filterValue(0.) { - SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateLevelOfDetail, 0); + SET_JOB_RUN_STAT_TYPE(this, JobTypes::UpdateLevelOfDetail, 0) } UpdateLevelOfDetailJob::~UpdateLevelOfDetailJob() @@ -229,23 +248,32 @@ void UpdateLevelOfDetailJob::setFrameGraphRoot(FrameGraphNode *frameGraphRoot) void UpdateLevelOfDetailJob::run() { + Q_D(UpdateLevelOfDetailJob); + Q_ASSERT(m_frameGraphRoot && m_root && m_manager); // short-circuit if no LoDs exist if (m_manager->levelOfDetailManager()->count() == 0) return; - - if (m_manager->levelOfDetailManager()->count() == 0) - return; // no LODs, lets bail out early - LODUpdateVisitor visitor(m_filterValue, m_frameGraphRoot, m_manager); visitor.apply(m_root); m_filterValue = visitor.filterValue(); + d->m_updatedIndices = visitor.updatedIndices(); } -} // Render +void UpdateLevelOfDetailJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) +{ + for (const auto &updatedNode: qAsConst(m_updatedIndices)) { + QLevelOfDetail *node = qobject_cast<QLevelOfDetail *>(manager->lookupNode(updatedNode.first)); + if (!node) + continue; + node->setCurrentIndex(updatedNode.second); + } +} + +} // Render } // Qt3DRender QT_END_NAMESPACE diff --git a/src/render/jobs/updatelevelofdetailjob_p.h b/src/render/jobs/updatelevelofdetailjob_p.h index 3c7d00d2c..9ac5cf0e9 100644 --- a/src/render/jobs/updatelevelofdetailjob_p.h +++ b/src/render/jobs/updatelevelofdetailjob_p.h @@ -65,6 +65,7 @@ class Entity; class NodeManagers; class LevelOfDetail; class FrameGraphNode; +class UpdateLevelOfDetailJobPrivate; class Q_3DRENDERSHARED_PRIVATE_EXPORT UpdateLevelOfDetailJob : public Qt3DCore::QAspectJob { @@ -81,6 +82,8 @@ public: Entity *root() const { return m_root; } private: + Q_DECLARE_PRIVATE(UpdateLevelOfDetailJob) + NodeManagers *m_manager; FrameGraphNode *m_frameGraphRoot; Entity *m_root; |