summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2019-10-03 15:50:42 +0100
committerMike Krus <mike.krus@kdab.com>2019-10-08 15:27:03 +0100
commitd3507c90e20a8f2b0a78428a3c78888dbe2138d9 (patch)
tree2e95f525b4f2003bd38fcad3dcf4df58b721815b
parentbf437f7da6c57307f93a24162981d4efd989fc53 (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.cpp9
-rw-r--r--src/render/frontend/qlevelofdetail.cpp29
-rw-r--r--src/render/frontend/qlevelofdetail.h1
-rw-r--r--src/render/frontend/qlevelofdetail_p.h2
-rw-r--r--src/render/frontend/qlevelofdetailswitch.cpp65
-rw-r--r--src/render/frontend/qlevelofdetailswitch.h4
-rw-r--r--src/render/frontend/qlevelofdetailswitch_p.h77
-rw-r--r--src/render/frontend/render-frontend.pri1
-rw-r--r--src/render/jobs/updatelevelofdetailjob.cpp46
-rw-r--r--src/render/jobs/updatelevelofdetailjob_p.h3
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 &center);
+ 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;