From a1e5040d578e55f9fccdfc1347d417508a91bd58 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 10:57:54 +0200 Subject: Update QCameraLens to use direct sync Change-Id: I5b1af685c640c218d3720d5339b14dfc913e01c5 Reviewed-by: Paul Lemire --- src/core/nodes/qnode.cpp | 3 ++ src/render/backend/cameralens.cpp | 88 ++++++++++++++++------------------- src/render/backend/cameralens_p.h | 6 +-- src/render/frontend/qcameralens.cpp | 15 ++++-- src/render/frontend/qcameralens_p.h | 21 ++++++++- src/render/frontend/qrenderaspect.cpp | 2 +- 6 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index 5c37e337e..2cea47372 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -687,6 +687,9 @@ QNodePrivate *QNodePrivate::get(QNode *q) return q->d_func(); } +/*! + \internal + */ const QNodePrivate *QNodePrivate::get(const QNode *q) { return q->d_func(); diff --git a/src/render/backend/cameralens.cpp b/src/render/backend/cameralens.cpp index f4815a4a9..7a5c1f7e6 100644 --- a/src/render/backend/cameralens.cpp +++ b/src/render/backend/cameralens.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -119,12 +118,43 @@ Matrix4x4 CameraLens::viewMatrix(const Matrix4x4 &worldTransform) return Matrix4x4(m); } -void CameraLens::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void CameraLens::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_projection = Matrix4x4(data.projectionMatrix); - m_exposure = data.exposure; + const QCameraLens *node = qobject_cast(frontEnd); + if (!node) + return; + + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + const Matrix4x4 projectionMatrix(node->projectionMatrix()); + if (projectionMatrix != m_projection) { + m_projection = projectionMatrix; + markDirty(AbstractRenderer::AllDirty); + } + + if (node->exposure() != m_exposure) { + m_exposure = node->exposure(); + markDirty(AbstractRenderer::AllDirty); + } + + const QCameraLensPrivate *d = static_cast(QNodePrivate::get(node)); + if (d->m_pendingViewAllCommand != m_pendingViewAllCommand) { + m_pendingViewAllCommand = d->m_pendingViewAllCommand; + + if (m_pendingViewAllCommand) { + const QVariant v = m_pendingViewAllCommand.data; + const QNodeCommand::CommandId commandId = m_pendingViewAllCommand.commandId; + + if (m_pendingViewAllCommand.name == QLatin1String("QueryRootBoundingVolume")) { + const QNodeId id = v.value(); + computeSceneBoundingVolume({}, id, commandId); + } else if (m_pendingViewAllCommand.name == QLatin1String("QueryEntityBoundingVolume")) { + const QVector ids = v.value>(); + if (ids.size() == 2) + computeSceneBoundingVolume(ids[0], ids[1], commandId); + } + } + } } void CameraLens::computeSceneBoundingVolume(QNodeId entityId, @@ -152,15 +182,16 @@ void CameraLens::computeSceneBoundingVolume(QNodeId entityId, void CameraLens::notifySceneBoundingVolume(const Sphere &sphere, QNodeCommand::CommandId commandId) { - if (m_pendingViewAllCommand != commandId) + if (!m_pendingViewAllCommand || m_pendingViewAllCommand.commandId != commandId) return; if (sphere.radius() > 0.f) { QVector data = { sphere.center().x(), sphere.center().y(), sphere.center().z(), sphere.radius() }; QVariant v; v.setValue(data); - sendCommand(QLatin1String("ViewAll"), v, m_pendingViewAllCommand); + sendCommand(QLatin1String("ViewAll"), v, m_pendingViewAllCommand.commandId); } + m_pendingViewAllCommand = {}; } void CameraLens::setProjection(const Matrix4x4 &projection) @@ -173,47 +204,6 @@ void CameraLens::setExposure(float exposure) m_exposure = exposure; } -void CameraLens::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case PropertyUpdated: { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - - if (propertyChange->propertyName() == QByteArrayLiteral("projectionMatrix")) { - QMatrix4x4 projectionMatrix = propertyChange->value().value(); - m_projection = Matrix4x4(projectionMatrix); - } else if (propertyChange->propertyName() == QByteArrayLiteral("exposure")) { - setExposure(propertyChange->value().toFloat()); - } - - markDirty(AbstractRenderer::AllDirty); - } - break; - - case CommandRequested: { - QNodeCommandPtr command = qSharedPointerCast(e); - - if (command->name() == QLatin1String("QueryRootBoundingVolume")) { - m_pendingViewAllCommand = command->commandId(); - QVariant v = command->data(); - QNodeId id = v.value(); - computeSceneBoundingVolume({}, id, command->commandId()); - } else if (command->name() == QLatin1String("QueryEntityBoundingVolume")) { - m_pendingViewAllCommand = command->commandId(); - QVariant v = command->data(); - QVector ids = v.value>(); - if (ids.size() == 2) - computeSceneBoundingVolume(ids[0], ids[1], command->commandId()); - } - } - break; - - default: - break; - } - BackendNode::sceneChangeEvent(e); -} - bool CameraLens::viewMatrixForCamera(EntityManager* manager, Qt3DCore::QNodeId cameraId, Matrix4x4 &viewMatrix, Matrix4x4 &projectionMatrix) { diff --git a/src/render/backend/cameralens_p.h b/src/render/backend/cameralens_p.h index 80a1715cf..bd721d5e9 100644 --- a/src/render/backend/cameralens_p.h +++ b/src/render/backend/cameralens_p.h @@ -54,6 +54,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -96,21 +97,20 @@ public: void setExposure(float exposure); inline float exposure() const { return m_exposure; } + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; void notifySceneBoundingVolume(const Sphere &sphere, Qt3DCore::QNodeCommand::CommandId commandId); static bool viewMatrixForCamera(EntityManager *manager, Qt3DCore::QNodeId cameraId, Matrix4x4 &viewMatrix, Matrix4x4 &projectionMatrix); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; void computeSceneBoundingVolume(Qt3DCore::QNodeId entityId, Qt3DCore::QNodeId cameraId, Qt3DCore::QNodeCommand::CommandId commandId); QRenderAspect *m_renderAspect; - Qt3DCore::QNodeCommand::CommandId m_pendingViewAllCommand; + CameraLensCommand m_pendingViewAllCommand; Matrix4x4 m_projection; float m_exposure; }; diff --git a/src/render/frontend/qcameralens.cpp b/src/render/frontend/qcameralens.cpp index 296421031..cf30b714a 100644 --- a/src/render/frontend/qcameralens.cpp +++ b/src/render/frontend/qcameralens.cpp @@ -228,13 +228,17 @@ QCameraLensPrivate::QCameraLensPrivate() { } + void QCameraLens::viewAll(Qt3DCore::QNodeId cameraId) { Q_D(QCameraLens); if (d->m_projectionType == PerspectiveProjection) { QVariant v; v.setValue(cameraId); - d->m_pendingViewAllCommand = sendCommand(QLatin1String("QueryRootBoundingVolume"), v); + d->m_pendingViewAllCommand = {QLatin1String("QueryRootBoundingVolume"), + v, + id()}; + d->update(); } } @@ -245,7 +249,10 @@ void QCameraLens::viewEntity(Qt3DCore::QNodeId entityId, Qt3DCore::QNodeId camer QVector ids = {entityId, cameraId}; QVariant v; v.setValue(ids); - d->m_pendingViewAllCommand = sendCommand(QLatin1String("QueryEntityBoundingVolume"), v); + d->m_pendingViewAllCommand = {QLatin1String("QueryEntityBoundingVolume"), + v, + id()}; + d->update(); } } @@ -253,7 +260,7 @@ void QCameraLensPrivate::processViewAllCommand(Qt3DCore::QNodeCommand::CommandId const QVariant &data) { Q_Q(QCameraLens); - if (m_pendingViewAllCommand != commandId) + if (!m_pendingViewAllCommand || m_pendingViewAllCommand.commandId != commandId) return; QVector boundingVolumeData = data.value< QVector >(); @@ -262,7 +269,7 @@ void QCameraLensPrivate::processViewAllCommand(Qt3DCore::QNodeCommand::CommandId QVector3D center(boundingVolumeData[0], boundingVolumeData[1], boundingVolumeData[2]); float radius = boundingVolumeData[3]; Q_EMIT q->viewSphere(center, radius); - m_pendingViewAllCommand = Qt3DCore::QNodeCommand::CommandId(); + m_pendingViewAllCommand = {}; } /*! diff --git a/src/render/frontend/qcameralens_p.h b/src/render/frontend/qcameralens_p.h index 111ab6522..01fcac0e5 100644 --- a/src/render/frontend/qcameralens_p.h +++ b/src/render/frontend/qcameralens_p.h @@ -65,6 +65,25 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +struct CameraLensCommand +{ + QString name; + QVariant data; + Qt3DCore::QNodeCommand::CommandId commandId; + + inline operator bool() const { return !name.isEmpty(); } +}; + +inline bool operator ==(const CameraLensCommand &a, const CameraLensCommand &b) noexcept +{ + return a.name == b.name && a.data == b.data && a.commandId == b.commandId; +} + +inline bool operator !=(const CameraLensCommand &a, const CameraLensCommand &b) noexcept +{ + return !(a == b); +} + class Q_3DRENDERSHARED_PRIVATE_EXPORT QCameraLensPrivate : public Qt3DCore::QComponentPrivate { public: @@ -106,7 +125,7 @@ public: float m_exposure; - Qt3DCore::QNodeCommand::CommandId m_pendingViewAllCommand; + CameraLensCommand m_pendingViewAllCommand; void processViewAllCommand(Qt3DCore::QNodeCommand::CommandId commandId, const QVariant &data); private: diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 67bcb6c02..08a85368f 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -255,7 +255,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer::create(m_renderer, q)); + q->registerBackendType(QSharedPointer::create(m_renderer, q)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); -- cgit v1.2.3 From 65b119725b44eb59e6c1e7f8d04f81d3712ab978 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Mon, 23 Sep 2019 07:24:36 +0200 Subject: Fix compile warning in imagesubmissioncontext.cpp Change-Id: I34f1dac63a31aadfeb893aca17b15d80184a24e4 Reviewed-by: Paul Lemire --- .../renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp index a5633c306..ca600f994 100644 --- a/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp +++ b/src/render/renderers/opengl/graphicshelpers/imagesubmissioncontext.cpp @@ -72,8 +72,10 @@ GLenum glAccessEnumForShaderImageAccess(QShaderImage::Access access) case QShaderImage::WriteOnly: return GL_WRITE_ONLY; case QShaderImage::ReadWrite: - return GL_READ_WRITE; + default: + break; } + return GL_READ_WRITE; } GLenum glImageFormatToGL(QShaderImage::ImageFormat format) -- cgit v1.2.3 From a364f08e6026eaebfdf6d0edf08d433c8814da84 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 20 Sep 2019 09:26:15 +0200 Subject: ClearBuffer: properly initialize clear color vector Change-Id: Ib2cb3ac47916ecdf3726e37ddd15cab4936ec3ff Reviewed-by: Paul Lemire --- src/render/framegraph/clearbuffers.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/render/framegraph/clearbuffers.cpp b/src/render/framegraph/clearbuffers.cpp index 98de30906..7d018c935 100644 --- a/src/render/framegraph/clearbuffers.cpp +++ b/src/render/framegraph/clearbuffers.cpp @@ -50,6 +50,8 @@ namespace Render { static QVector4D vec4dFromColor(const QColor &color) { + if (!color.isValid()) + return QVector4D(0.0f, 0.0f, 0.0f, 1.0f); return QVector4D(color.redF(), color.greenF(), color.blueF(), color.alphaF()); } @@ -58,6 +60,8 @@ ClearBuffers::ClearBuffers() , m_type(QClearBuffers::None) , m_clearDepthValue(1.f) , m_clearStencilValue(0) + , m_clearColorAsColor(Qt::black) + , m_clearColor(vec4dFromColor(m_clearColorAsColor)) { } -- cgit v1.2.3 From 3ad357371468c0da04b2964f040da41506379178 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 28 Aug 2019 11:01:40 -0500 Subject: Support transient enablement in QSubtreeEnabler Change-Id: I422cf0fb0991319b0f54e5a26b9b3694cb093454 Reviewed-by: Paul Lemire --- src/render/framegraph/framegraph.pri | 1 + src/render/framegraph/framegraphvisitor.cpp | 19 +++++- src/render/framegraph/framegraphvisitor_p.h | 2 + src/render/framegraph/qsubtreeenabler.cpp | 78 +++++++++++++++++++++- src/render/framegraph/qsubtreeenabler.h | 21 ++++++ src/render/framegraph/qsubtreeenabler_p.h | 80 +++++++++++++++++++++++ src/render/framegraph/subtreeenabler.cpp | 37 ++++++++++- src/render/framegraph/subtreeenabler_p.h | 8 +++ src/render/jobs/job_common_p.h | 1 + src/render/renderers/opengl/renderer/renderer.cpp | 24 +++++++ src/render/renderers/opengl/renderer/renderer_p.h | 3 + 11 files changed, 268 insertions(+), 6 deletions(-) create mode 100644 src/render/framegraph/qsubtreeenabler_p.h diff --git a/src/render/framegraph/framegraph.pri b/src/render/framegraph/framegraph.pri index e833d4590..bb833422f 100644 --- a/src/render/framegraph/framegraph.pri +++ b/src/render/framegraph/framegraph.pri @@ -68,6 +68,7 @@ HEADERS += \ $$PWD/qnopicking.h \ $$PWD/nopicking_p.h \ $$PWD/qsubtreeenabler.h \ + $$PWD/qsubtreeenabler_p.h \ $$PWD/subtreeenabler_p.h SOURCES += \ diff --git a/src/render/framegraph/framegraphvisitor.cpp b/src/render/framegraph/framegraphvisitor.cpp index 5ccad87e1..9af0297a0 100644 --- a/src/render/framegraph/framegraphvisitor.cpp +++ b/src/render/framegraph/framegraphvisitor.cpp @@ -41,6 +41,7 @@ #include "framegraphvisitor_p.h" #include "framegraphnode_p.h" +#include "subtreeenabler_p.h" #include #include #include @@ -61,6 +62,7 @@ FrameGraphVisitor::FrameGraphVisitor(const FrameGraphManager *manager) QVector FrameGraphVisitor::traverse(FrameGraphNode *root) { m_leaves.clear(); + m_enablersToDisable.clear(); Q_ASSERT_X(root, Q_FUNC_INFO, "The FrameGraphRoot is null"); @@ -72,10 +74,23 @@ QVector FrameGraphVisitor::traverse(FrameGraphNode *root) return m_leaves; } +// intended to be called after traverse +// (returns data that is captured during the traverse) +QVector &&FrameGraphVisitor::takeEnablersToDisable() +{ + return std::move(m_enablersToDisable); +} + void FrameGraphVisitor::visit(Render::FrameGraphNode *node) { - if (node->nodeType() == Render::FrameGraphNode::SubtreeEnabler && !node->isEnabled()) - return; + if (node->nodeType() == Render::FrameGraphNode::SubtreeEnabler) { + if (!node->isEnabled()) + return; + if (static_cast(node)->enablement() == QSubtreeEnabler::SingleShot) { + node->setEnabled(false); + m_enablersToDisable.push_back(node); + } + } // Recurse to children (if we have any), otherwise if this is a leaf node, // initiate a rendering from the current camera diff --git a/src/render/framegraph/framegraphvisitor_p.h b/src/render/framegraph/framegraphvisitor_p.h index f4c0d7796..5706a169d 100644 --- a/src/render/framegraph/framegraphvisitor_p.h +++ b/src/render/framegraph/framegraphvisitor_p.h @@ -72,12 +72,14 @@ public: explicit FrameGraphVisitor(const FrameGraphManager *nodeManager); QVector traverse(FrameGraphNode *root); + QVector &&takeEnablersToDisable(); private: void visit(Render::FrameGraphNode *node); const FrameGraphManager *m_manager; QVector m_leaves; + QVector m_enablersToDisable; }; } // namespace Render diff --git a/src/render/framegraph/qsubtreeenabler.cpp b/src/render/framegraph/qsubtreeenabler.cpp index 5355b6fbd..d2c25852b 100644 --- a/src/render/framegraph/qsubtreeenabler.cpp +++ b/src/render/framegraph/qsubtreeenabler.cpp @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#include -#include +#include "qsubtreeenabler_p.h" +#include QT_BEGIN_NAMESPACE @@ -100,7 +100,7 @@ namespace Qt3DRender */ QSubtreeEnabler::QSubtreeEnabler(Qt3DCore::QNode *parent) - : QFrameGraphNode(*new QFrameGraphNodePrivate, parent) + : QFrameGraphNode(*new QSubtreeEnablerPrivate, parent) { } @@ -108,6 +108,78 @@ QSubtreeEnabler::~QSubtreeEnabler() { } +/*! + \enum QSubtreeEnabler::Enablement + + Specifies whether subtree enablement is persistent or transient. + + \value Persistent + The value of enabled is persistent. This is the default. + + \value SingleShot + The value of enabled will last for a single frame and then be reset to false. + This might be used for a subtree drawing to an FBO, for example, to only update + the FBO when the relevant portions of the scene changed. +*/ + +/*! + \qmlproperty enumeration Qt3D.Render::SubtreeEnabler::enablement + Controls whether subtree enablement is persistent or transient. + + \value Persistent + The value of enabled is persistent. This is the default. + + \value SingleShot + The value of enabled will last for a single frame and then be reset to false. + This might be used for a subtree drawing to an FBO, for example, to only update + the FBO when the relevant portions of the scene changed. +*/ + +/*! + \property Qt3DRender::QSubtreeEnabler::enablement + Controls whether subtree enablement is persistent or transient. +*/ +QSubtreeEnabler::Enablement QSubtreeEnabler::enablement() const +{ + Q_D(const QSubtreeEnabler); + return d->m_enablement; +} + +void QSubtreeEnabler::setEnablement(QSubtreeEnabler::Enablement enablement) +{ + Q_D(QSubtreeEnabler); + if (d->m_enablement == enablement) + return; + d->m_enablement = enablement; + emit enablementChanged(d->m_enablement); +} + +/*! + \qmlmethod void Qt3D.Render::SubtreeEnabler::requestUpdate() + Requests that the subtree be enabled. + + A conveninence method intended to be used with \c SingleShot enablement. + */ + +/*! + Requests that the subtree be enabled. + + A conveninence method intended to be used with \c SingleShot enablement. + */ +void QSubtreeEnabler::requestUpdate() +{ + setEnabled(true); +} + +Qt3DCore::QNodeCreatedChangeBasePtr QSubtreeEnabler::createNodeCreationChange() const +{ + auto creationChange = QFrameGraphNodeCreatedChangePtr::create(this); + auto &data = creationChange->data; + Q_D(const QSubtreeEnabler); + data.enablement = d->m_enablement; + return creationChange; +} + } //Qt3DRender QT_END_NAMESPACE diff --git a/src/render/framegraph/qsubtreeenabler.h b/src/render/framegraph/qsubtreeenabler.h index 82334b3da..558e3b8b7 100644 --- a/src/render/framegraph/qsubtreeenabler.h +++ b/src/render/framegraph/qsubtreeenabler.h @@ -47,12 +47,33 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { +class QSubtreeEnablerPrivate; + class Q_3DRENDERSHARED_EXPORT QSubtreeEnabler : public QFrameGraphNode { Q_OBJECT + Q_PROPERTY(Enablement enablement READ enablement WRITE setEnablement NOTIFY enablementChanged) public: explicit QSubtreeEnabler(Qt3DCore::QNode *parent = nullptr); ~QSubtreeEnabler(); + + enum Enablement { + Persistent, + SingleShot + }; + Q_ENUM(Enablement) + + Enablement enablement() const; + void setEnablement(Enablement enablement); + + Q_INVOKABLE void requestUpdate(); + +Q_SIGNALS: + void enablementChanged(Qt3DRender::QSubtreeEnabler::Enablement enablement); + +private: + Q_DECLARE_PRIVATE(QSubtreeEnabler) + Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; }; } //Qt3DRender diff --git a/src/render/framegraph/qsubtreeenabler_p.h b/src/render/framegraph/qsubtreeenabler_p.h new file mode 100644 index 000000000..72354fe89 --- /dev/null +++ b/src/render/framegraph/qsubtreeenabler_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Ford Motor Company +** 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_QSUBTREEENABLER_P_H +#define QT3DRENDER_QSUBTREEENABLER_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 "qsubtreeenabler.h" +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QSubtreeEnablerPrivate : public QFrameGraphNodePrivate +{ +public: + QSubtreeEnablerPrivate() = default; + + QSubtreeEnabler::Enablement m_enablement = QSubtreeEnabler::Persistent; + + Q_DECLARE_PUBLIC(QSubtreeEnabler) +}; + +struct QSubtreeEnablerData +{ + QSubtreeEnabler::Enablement enablement; +}; + +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_QSUBTREEENABLER_P_H diff --git a/src/render/framegraph/subtreeenabler.cpp b/src/render/framegraph/subtreeenabler.cpp index e4b4e4ba7..160e1a5b5 100644 --- a/src/render/framegraph/subtreeenabler.cpp +++ b/src/render/framegraph/subtreeenabler.cpp @@ -38,6 +38,8 @@ ****************************************************************************/ #include "subtreeenabler_p.h" +#include +#include QT_BEGIN_NAMESPACE @@ -46,10 +48,43 @@ namespace Qt3DRender { namespace Render { SubtreeEnabler::SubtreeEnabler() - : FrameGraphNode(FrameGraphNode::SubtreeEnabler) + : FrameGraphNode(FrameGraphNode::SubtreeEnabler, FrameGraphNode::ReadWrite) { } +void SubtreeEnabler::sendDisableToFrontend() +{ + if (m_enablement != QSubtreeEnabler::SingleShot) + return; + + if (isEnabled()) + return; + + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + e->setPropertyName("enabled"); + e->setValue(false); + notifyObservers(e); +} + +void SubtreeEnabler::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) +{ + const QSubtreeEnabler *node = qobject_cast(frontEnd); + if (!node) + return; + + if (node->isEnabled() != isEnabled()) + markDirty(AbstractRenderer::AllDirty); + + FrameGraphNode::syncFromFrontEnd(frontEnd, firstTime); + + const auto enablement = node->enablement(); + if (enablement != m_enablement) { + m_enablement = enablement; + markDirty(AbstractRenderer::FrameGraphDirty); + } +} + } //Render } //Qt3DRender diff --git a/src/render/framegraph/subtreeenabler_p.h b/src/render/framegraph/subtreeenabler_p.h index 22782da12..2de8dfabf 100644 --- a/src/render/framegraph/subtreeenabler_p.h +++ b/src/render/framegraph/subtreeenabler_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include #include QT_BEGIN_NAMESPACE @@ -63,6 +64,13 @@ class Q_AUTOTEST_EXPORT SubtreeEnabler : public FrameGraphNode { public: SubtreeEnabler(); + QSubtreeEnabler::Enablement enablement() const { return m_enablement; } + void sendDisableToFrontend(); + + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; + +private: + QSubtreeEnabler::Enablement m_enablement = QSubtreeEnabler::Persistent; }; } //Render diff --git a/src/render/jobs/job_common_p.h b/src/render/jobs/job_common_p.h index 9c83624b8..7aa6f64ba 100644 --- a/src/render/jobs/job_common_p.h +++ b/src/render/jobs/job_common_p.h @@ -109,6 +109,7 @@ namespace JobTypes { UpdateLayerEntity, SendTextureChangesToFrontend, SendSetFenceHandlesToFrontend, + SendDisablesToFrontend }; } // JobTypes diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 2df3d1270..a05e128a2 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -197,6 +198,7 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_textureGathererJob(Render::GenericLambdaJobPtr>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) , m_sendTextureChangesToFrontendJob(Render::GenericLambdaJobPtr>::create([this] { sendTextureChangesToFrontend(); }, JobTypes::SendTextureChangesToFrontend)) , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) + , m_sendDisablesToFrontendJob(Render::GenericLambdaJobPtr>::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) , m_introspectShaderJob(Render::GenericLambdaJobPtr>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) , m_syncLoadingJobs(Render::GenericLambdaJobPtr>::create([] {}, JobTypes::SyncLoadingJobs)) , m_ownedContext(false) @@ -1204,6 +1206,21 @@ void Renderer::sendSetFenceHandlesToFrontend() } } +// Executed in a job +void Renderer::sendDisablesToFrontend() +{ + const auto updatedDisables = std::move(m_updatedDisables); + FrameGraphManager *fgManager = m_nodesManager->frameGraphManager(); + for (const auto &nodeId : updatedDisables) { + FrameGraphNode *fgNode = fgManager->lookupNode(nodeId); + if (fgNode != nullptr) { // Node could have been deleted before we got a chance to notify it + Q_ASSERT(fgNode->nodeType() == FrameGraphNode::SubtreeEnabler); + SubtreeEnabler *enabler = static_cast(fgNode); + enabler->sendDisableToFrontend(); + } + } +} + // Render Thread (or QtQuick RenderThread when using Scene3D) // Scene3D: When using Scene3D rendering, we can't assume that when // updateGLResources is called, the resource handles points to still existing @@ -1811,6 +1828,13 @@ QVector Renderer::renderBinJobs() FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); const QVector fgLeaves = visitor.traverse(frameGraphRoot()); + // Handle single shot subtree enablers + const auto subtreeEnablers = visitor.takeEnablersToDisable(); + for (auto *node : subtreeEnablers) + m_updatedDisables.push_back(node->peerId()); + if (m_updatedDisables.size() > 0) + renderBinJobs.push_back(m_sendDisablesToFrontendJob); + // Remove leaf nodes that no longer exist from cache const QList keys = m_cache.leafNodeCache.keys(); for (FrameGraphNode *leafNode : keys) { diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index bfab85e4f..0ea27d91a 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -381,6 +381,7 @@ private: GenericLambdaJobPtr> m_textureGathererJob; GenericLambdaJobPtr> m_sendTextureChangesToFrontendJob; GenericLambdaJobPtr> m_sendSetFenceHandlesToFrontendJob; + GenericLambdaJobPtr> m_sendDisablesToFrontendJob; IntrospectShadersJobPtr m_introspectShaderJob; SynchronizerJobPtr m_syncLoadingJobs; @@ -392,6 +393,7 @@ private: void reloadDirtyShaders(); void sendTextureChangesToFrontend(); void sendSetFenceHandlesToFrontend(); + void sendDisablesToFrontend(); QMutex m_abandonedVaosMutex; QVector m_abandonedVaos; @@ -402,6 +404,7 @@ private: QVector m_dirtyTextures; QVector> m_updatedTextureProperties; QVector> m_updatedSetFences; + QVector m_updatedDisables; Qt3DCore::QNodeIdVector m_textureIdsToCleanup; bool m_ownedContext; -- cgit v1.2.3 From fc32576389478022355b36a395b733be7f2efa76 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 11:09:58 +0200 Subject: Update QLayer to use direct sync Change-Id: Iadcbc7f2262acdaea7ac78d568e764f4f193ea58 Reviewed-by: Paul Lemire --- src/render/backend/layer.cpp | 33 ++++++++++++++------------------- src/render/backend/layer_p.h | 4 +--- src/render/frontend/qrenderaspect.cpp | 2 +- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/render/backend/layer.cpp b/src/render/backend/layer.cpp index 24ec284fc..f0c844906 100644 --- a/src/render/backend/layer.cpp +++ b/src/render/backend/layer.cpp @@ -67,27 +67,22 @@ void Layer::cleanup() QBackendNode::setEnabled(false); } -void Layer::sceneChangeEvent(const QSceneChangePtr &e) +void Layer::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - QByteArray propertyName = propertyChange->propertyName(); - if (propertyName == QByteArrayLiteral("recursive")) { - m_recursive = propertyChange->value().toBool(); - markDirty(AbstractRenderer::LayersDirty); - } - if (propertyName == QByteArrayLiteral("enabled")) - markDirty(AbstractRenderer::LayersDirty); - } - BackendNode::sceneChangeEvent(e); -} + const QLayer *node = qobject_cast(frontEnd); + if (!node) + return; -void Layer::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) -{ - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_recursive = data.m_recursive; - markDirty(AbstractRenderer::LayersDirty); + const bool oldEnabled = isEnabled(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (isEnabled() != oldEnabled || firstTime) + markDirty(AbstractRenderer::LayersDirty); + + if (node->recursive() != m_recursive) { + m_recursive = node->recursive(); + markDirty(AbstractRenderer::LayersDirty); + } } bool Layer::recursive() const diff --git a/src/render/backend/layer_p.h b/src/render/backend/layer_p.h index 1513157f9..8631e2d92 100644 --- a/src/render/backend/layer_p.h +++ b/src/render/backend/layer_p.h @@ -76,11 +76,9 @@ public: bool recursive() const; void setRecursive(bool recursive); -protected: - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; bool m_recursive; }; diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 08a85368f..da775ce49 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -256,7 +256,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, q)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); -- cgit v1.2.3 From acf75b238477b86fc67137ecd12959305b6dc117 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 11:29:22 +0200 Subject: Update QLevelOfDetail to use direct sync Change-Id: I7ef8ae7cd9509939f85280abc6eefe8210dc556d Reviewed-by: Paul Lemire --- src/render/backend/levelofdetail.cpp | 66 ++++++++++++---------- src/render/backend/levelofdetail_p.h | 3 +- src/render/frontend/qrenderaspect.cpp | 2 +- .../render/levelofdetail/tst_levelofdetail.cpp | 38 ++++++------- 4 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/render/backend/levelofdetail.cpp b/src/render/backend/levelofdetail.cpp index 157bfc004..08410edf9 100644 --- a/src/render/backend/levelofdetail.cpp +++ b/src/render/backend/levelofdetail.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -64,41 +65,48 @@ LevelOfDetail::~LevelOfDetail() cleanup(); } -void LevelOfDetail::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) +void LevelOfDetail::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_camera = data.camera; - m_currentIndex = data.currentIndex; - m_thresholdType = data.thresholdType; - m_thresholds = data.thresholds; - m_volumeOverride = data.volumeOverride; -} + const QLevelOfDetail *node = qobject_cast(frontEnd); + if (!node) + return; -void LevelOfDetail::cleanup() -{ - QBackendNode::setEnabled(false); -} + const bool oldEnabled = isEnabled(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); -void LevelOfDetail::sceneChangeEvent(const QSceneChangePtr &e) -{ - if (e->type() == PropertyUpdated) { - const QPropertyUpdatedChangePtr &propertyChange = qSharedPointerCast(e); - if (propertyChange->propertyName() == QByteArrayLiteral("currentIndex")) - m_currentIndex = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("camera")) - m_camera = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("thresholdType")) - m_thresholdType = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("thresholds")) - m_thresholds = propertyChange->value().value>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("volumeOverride")) - m_volumeOverride = propertyChange->value().value(); + const Qt3DCore::QNodeId cameraId = Qt3DCore::qIdForNode(node->camera()); + if (cameraId != m_camera) { + m_camera = cameraId; + markDirty(AbstractRenderer::GeometryDirty); + } + + if (node->currentIndex() != m_currentIndex) { + m_currentIndex = node->currentIndex(); + markDirty(AbstractRenderer::GeometryDirty); + } + + if (node->thresholdType() != m_thresholdType) { + m_thresholdType = node->thresholdType(); + markDirty(AbstractRenderer::GeometryDirty); } - markDirty(AbstractRenderer::GeometryDirty); + if (node->thresholds() != m_thresholds) { + m_thresholds = node->thresholds(); + markDirty(AbstractRenderer::GeometryDirty); + } - BackendNode::sceneChangeEvent(e); + if (node->volumeOverride() != m_volumeOverride) { + m_volumeOverride = node->volumeOverride(); + markDirty(AbstractRenderer::GeometryDirty); + } + + if (isEnabled() != oldEnabled || firstTime) + markDirty(AbstractRenderer::LayersDirty); +} + +void LevelOfDetail::cleanup() +{ + QBackendNode::setEnabled(false); } void LevelOfDetail::setCurrentIndex(int currentIndex) diff --git a/src/render/backend/levelofdetail_p.h b/src/render/backend/levelofdetail_p.h index 4cf835d9b..8399e19b7 100644 --- a/src/render/backend/levelofdetail_p.h +++ b/src/render/backend/levelofdetail_p.h @@ -73,7 +73,7 @@ public: LevelOfDetail(); ~LevelOfDetail(); void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) final; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; Qt3DCore::QNodeId camera() const { return m_camera; } int currentIndex() const { return m_currentIndex; } @@ -86,7 +86,6 @@ public: void setCurrentIndex(int currentIndex); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; Qt3DCore::QNodeId m_camera; int m_currentIndex; QLevelOfDetail::ThresholdType m_thresholdType; diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index da775ce49..d4d285c37 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -257,7 +257,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer::create(m_renderer, q)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/tests/auto/render/levelofdetail/tst_levelofdetail.cpp b/tests/auto/render/levelofdetail/tst_levelofdetail.cpp index 148c54e58..2285cc5ff 100644 --- a/tests/auto/render/levelofdetail/tst_levelofdetail.cpp +++ b/tests/auto/render/levelofdetail/tst_levelofdetail.cpp @@ -45,11 +45,13 @@ private Q_SLOTS: void checkPeerPropertyMirroring() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::LevelOfDetail renderLod; Qt3DRender::QLevelOfDetail lod; // WHEN - simulateInitialization(&lod, &renderLod); + renderLod.setRenderer(&renderer); + simulateInitializationSync(&lod, &renderLod); // THEN QCOMPARE(renderLod.peerId(), lod.id()); @@ -82,7 +84,7 @@ private Q_SLOTS: // WHEN renderLod.setRenderer(&renderer); - simulateInitialization(&lod, &renderLod); + simulateInitializationSync(&lod, &renderLod); // THEN QCOMPARE(renderLod.thresholdType(), lod.thresholdType()); @@ -92,8 +94,10 @@ private Q_SLOTS: { // GIVEN TestRenderer renderer; + Qt3DRender::QLevelOfDetail lod; Qt3DRender::Render::LevelOfDetail renderLod; renderLod.setRenderer(&renderer); + simulateInitializationSync(&lod, &renderLod); // THEN QVERIFY(renderLod.thresholdType() != Qt3DRender::QLevelOfDetail::ProjectedScreenPixelSizeThreshold); @@ -101,38 +105,30 @@ private Q_SLOTS: { // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(static_cast(Qt3DRender::QLevelOfDetail::ProjectedScreenPixelSizeThreshold)); - updateChange->setPropertyName("thresholdType"); - renderLod.sceneChangeEvent(updateChange); + lod.setThresholdType(Qt3DRender::QLevelOfDetail::ProjectedScreenPixelSizeThreshold); + renderLod.syncFromFrontEnd(&lod, false); // THEN QCOMPARE(renderLod.thresholdType(), Qt3DRender::QLevelOfDetail::ProjectedScreenPixelSizeThreshold); - QVERIFY(renderer.dirtyBits() != 0); - } + QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty); + renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); } { - QVector thresholds = {20.f, 30.f, 40.f}; - QVariant v; - v.setValue(thresholds); + const QVector thresholds = {20.f, 30.f, 40.f}; // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(v); - updateChange->setPropertyName("thresholds"); - renderLod.sceneChangeEvent(updateChange); - + lod.setThresholds(thresholds); + renderLod.syncFromFrontEnd(&lod, false); // THEN QCOMPARE(renderLod.thresholds(), thresholds); } { // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - Qt3DRender::QLevelOfDetailBoundingSphere sphere(QVector3D(1.0f, 2.0f, 3.0f), 1.0f); - updateChange->setValue(QVariant::fromValue(sphere)); - updateChange->setPropertyName("volumeOverride"); - renderLod.sceneChangeEvent(updateChange); + const Qt3DRender::QLevelOfDetailBoundingSphere sphere(QVector3D(1.0f, 2.0f, 3.0f), 1.0f); + // WHEN + lod.setVolumeOverride(sphere); + renderLod.syncFromFrontEnd(&lod, false); // THEN QCOMPARE(renderLod.center(), QVector3D(1., 2., 3.)); -- cgit v1.2.3 From 56f50210f5eaf603cbb4def1b012a793cf6cc01d Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 11:59:26 +0200 Subject: Update QLevelOfDetailSwitch to use direct sync Change-Id: Ic5a50f04f73512013c8e01a851d46276b6c65454 Reviewed-by: Paul Lemire --- src/render/frontend/qrenderaspect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index d4d285c37..3c244f0f5 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -258,7 +258,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer::create(m_renderer, q)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); -- cgit v1.2.3 From 26ae3af8b1bcadf608b24160601eb0d772bd20ce Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 12:12:18 +0200 Subject: Update QSceneLoader to use direct sync Change-Id: Iae97dca09ae84236caa4e5383f05a4ce7b7226ea Reviewed-by: Paul Lemire --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/io/scene.cpp | 42 +++++++---------------- src/render/io/scene_p.h | 4 +-- tests/auto/render/sceneloader/tst_sceneloader.cpp | 36 +++++++++---------- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 3c244f0f5..256c88e3e 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -259,7 +259,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); + q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer)); diff --git a/src/render/io/scene.cpp b/src/render/io/scene.cpp index d95f42a48..e7f289f8a 100644 --- a/src/render/io/scene.cpp +++ b/src/render/io/scene.cpp @@ -76,36 +76,20 @@ void Scene::setStatus(QSceneLoader::Status status) notifyObservers(e); } -void Scene::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void Scene::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_source = data.source; - Q_ASSERT(m_sceneManager); - if (Qt3DCore::QDownloadHelperService::isLocal(m_source)) - m_sceneManager->addSceneData(m_source, peerId()); - else - m_sceneManager->startSceneDownload(m_source, peerId()); -} - -void Scene::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (propertyChange->propertyName() == QByteArrayLiteral("source")) { - m_source = propertyChange->value().toUrl(); - - // If the source is empty -> we need to unload anything that was - // previously loaded and reset the status accordingly. This means - // we need to call addSceneData with the empty source to send a - // change to the frontend that will trigger the removal of the - // previous scene. The reason this scheme is employed is because - // the backend also takes care of updating the status. - if (m_source.isEmpty() || Qt3DCore::QDownloadHelperService::isLocal(m_source)) - m_sceneManager->addSceneData(m_source, peerId()); - else - m_sceneManager->startSceneDownload(m_source, peerId()); - } + const QSceneLoader *node = qobject_cast(frontEnd); + if (!node) + return; + + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (node->source() != m_source) { + m_source = node->source(); + if (m_source.isEmpty() || Qt3DCore::QDownloadHelperService::isLocal(m_source)) + m_sceneManager->addSceneData(m_source, peerId()); + else + m_sceneManager->startSceneDownload(m_source, peerId()); } markDirty(AbstractRenderer::AllDirty); } diff --git a/src/render/io/scene_p.h b/src/render/io/scene_p.h index 631f23124..04b9bba1a 100644 --- a/src/render/io/scene_p.h +++ b/src/render/io/scene_p.h @@ -72,7 +72,7 @@ class Q_AUTOTEST_EXPORT Scene : public BackendNode public: Scene(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; QUrl source() const; void setSceneSubtree(Qt3DCore::QEntity *subTree); void setSceneManager(SceneManager *manager); @@ -81,8 +81,6 @@ public: void setStatus(QSceneLoader::Status status); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - SceneManager *m_sceneManager; QUrl m_source; }; diff --git a/tests/auto/render/sceneloader/tst_sceneloader.cpp b/tests/auto/render/sceneloader/tst_sceneloader.cpp index 8da82b609..e5ea8b6c1 100644 --- a/tests/auto/render/sceneloader/tst_sceneloader.cpp +++ b/tests/auto/render/sceneloader/tst_sceneloader.cpp @@ -46,6 +46,7 @@ private Q_SLOTS: void checkInitialAndCleanedUpState() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Scene sceneLoader; Qt3DRender::Render::SceneManager sceneManager; @@ -61,8 +62,9 @@ private Q_SLOTS: frontendSceneLoader.setSource(newUrl); // WHEN + sceneLoader.setRenderer(&renderer); sceneLoader.setSceneManager(&sceneManager); - simulateInitialization(&frontendSceneLoader, &sceneLoader); + simulateInitializationSync(&frontendSceneLoader, &sceneLoader); // THEN QVERIFY(!sceneLoader.peerId().isNull()); @@ -78,6 +80,7 @@ private Q_SLOTS: void checkPeerPropertyMirroring() { // GIVEN + TestRenderer renderer; Qt3DRender::QSceneLoader frontendSceneLoader; frontendSceneLoader.setSource(QUrl(QStringLiteral("file:///CorvetteMuseum"))); @@ -85,8 +88,9 @@ private Q_SLOTS: Qt3DRender::Render::SceneManager sceneManager; // WHEN + sceneLoader.setRenderer(&renderer); sceneLoader.setSceneManager(&sceneManager); - simulateInitialization(&frontendSceneLoader, &sceneLoader); + simulateInitializationSync(&frontendSceneLoader, &sceneLoader); // THEN QCOMPARE(sceneLoader.peerId(), frontendSceneLoader.id()); @@ -100,29 +104,27 @@ private Q_SLOTS: TestRenderer renderer; Qt3DRender::Render::Scene sceneLoader; Qt3DRender::Render::SceneManager sceneManager; + Qt3DRender::QSceneLoader frontendSceneLoader; sceneLoader.setRenderer(&renderer); sceneLoader.setSceneManager(&sceneManager); + simulateInitializationSync(&frontendSceneLoader, &sceneLoader); // THEN QVERIFY(sceneManager.takePendingSceneLoaderJobs().isEmpty()); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); const QUrl newUrl(QStringLiteral("file:///Bownling_Green_KY")); - updateChange->setValue(newUrl); - updateChange->setPropertyName("source"); - sceneLoader.sceneChangeEvent(updateChange); + frontendSceneLoader.setSource(newUrl); + sceneLoader.syncFromFrontEnd(&frontendSceneLoader, false); // THEN QCOMPARE(sceneLoader.source(), newUrl); QVERIFY(!sceneManager.takePendingSceneLoaderJobs().isEmpty()); // WHEN - updateChange = QSharedPointer::create(Qt3DCore::QNodeId()); - updateChange->setValue(false); - updateChange->setPropertyName("enabled"); - sceneLoader.sceneChangeEvent(updateChange); + frontendSceneLoader.setEnabled(false); + sceneLoader.syncFromFrontEnd(&frontendSceneLoader, false); // THEN QCOMPARE(sceneLoader.isEnabled(), false); @@ -179,29 +181,27 @@ private Q_SLOTS: TestRenderer renderer; Qt3DRender::Render::Scene sceneLoader; Qt3DRender::Render::SceneManager sceneManager; + Qt3DRender::QSceneLoader frontendSceneLoader; sceneLoader.setRenderer(&renderer); sceneLoader.setSceneManager(&sceneManager); + simulateInitializationSync(&frontendSceneLoader, &sceneLoader); // THEN QVERIFY(sceneManager.takePendingSceneLoaderJobs().isEmpty()); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); const QUrl newUrl(QStringLiteral("file:///Bownling_Green_KY")); - updateChange->setValue(newUrl); - updateChange->setPropertyName("source"); - sceneLoader.sceneChangeEvent(updateChange); + frontendSceneLoader.setSource(newUrl); + sceneLoader.syncFromFrontEnd(&frontendSceneLoader, false); // THEN QCOMPARE(sceneLoader.source(), newUrl); QVERIFY(!sceneManager.takePendingSceneLoaderJobs().isEmpty()); // WHEN - updateChange.reset(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(QUrl()); - updateChange->setPropertyName("source"); - sceneLoader.sceneChangeEvent(updateChange); + frontendSceneLoader.setSource(QUrl()); + sceneLoader.syncFromFrontEnd(&frontendSceneLoader, false); // THEN -> we should still have generated a job to reset the scene (immediately) QCOMPARE(sceneLoader.source(), QUrl()); -- cgit v1.2.3 From 6370b00fc647f4c064f5c83cda8f0a5fb82a7fbf Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 12:28:25 +0200 Subject: Update QRenderTarget to use direct sync Change-Id: Ie0261d21c63f2df798b1eb82aae05fb3440f71e5 Reviewed-by: Paul Lemire --- src/render/backend/rendertarget.cpp | 45 +++++++--------------- src/render/backend/rendertarget_p.h | 4 +- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/frontend/qrendertarget.cpp | 12 +----- .../render/qrendertarget/tst_qrendertarget.cpp | 20 ++++------ .../auto/render/rendertarget/tst_rendertarget.cpp | 30 ++++++++------- 6 files changed, 43 insertions(+), 70 deletions(-) diff --git a/src/render/backend/rendertarget.cpp b/src/render/backend/rendertarget.cpp index b0565a26b..206f64e4e 100644 --- a/src/render/backend/rendertarget.cpp +++ b/src/render/backend/rendertarget.cpp @@ -58,11 +58,21 @@ RenderTarget::RenderTarget() { } -void RenderTarget::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void RenderTarget::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_renderOutputs = data.outputIds; + const QRenderTarget *node = qobject_cast(frontEnd); + if (!node) + return; + + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + auto outputIds = qIdsForNodes(node->outputs()); + std::sort(std::begin(outputIds), std::end(outputIds)); + + if (m_renderOutputs != outputIds) { + m_renderOutputs = outputIds; + markDirty(AbstractRenderer::AllDirty); + } } void RenderTarget::cleanup() @@ -87,33 +97,6 @@ QVector RenderTarget::renderOutputs() const return m_renderOutputs; } -void RenderTarget::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case Qt3DCore::PropertyValueAdded: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("output")) { - appendRenderOutput(change->addedNodeId()); - markDirty(AbstractRenderer::AllDirty); - } - break; - } - - case Qt3DCore::PropertyValueRemoved: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("output")) { - removeRenderOutput(change->removedNodeId()); - markDirty(AbstractRenderer::AllDirty); - } - break; - } - - default: - break; - } - BackendNode::sceneChangeEvent(e); -} - } // namespace Render } // namespace Qt3DRender diff --git a/src/render/backend/rendertarget_p.h b/src/render/backend/rendertarget_p.h index 5e3e63582..30769dcfc 100644 --- a/src/render/backend/rendertarget_p.h +++ b/src/render/backend/rendertarget_p.h @@ -76,11 +76,9 @@ public: QVector renderOutputs() const; - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - QVector m_renderOutputs; }; diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 256c88e3e..1aef960f3 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -260,7 +260,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/src/render/frontend/qrendertarget.cpp b/src/render/frontend/qrendertarget.cpp index 9aa9c8c41..2a74db775 100644 --- a/src/render/frontend/qrendertarget.cpp +++ b/src/render/frontend/qrendertarget.cpp @@ -126,11 +126,7 @@ void QRenderTarget::addOutput(QRenderTargetOutput *output) if (!output->parent()) output->setParent(this); - if (d->m_changeArbiter != nullptr) { - const auto change = QPropertyNodeAddedChangePtr::create(id(), output); - change->setPropertyName("output"); - d->notifyObservers(change); - } + d->update(); } } @@ -141,11 +137,7 @@ void QRenderTarget::removeOutput(QRenderTargetOutput *output) { Q_D(QRenderTarget); - if (output && d->m_changeArbiter != nullptr) { - const auto change = QPropertyNodeRemovedChangePtr::create(id(), output); - change->setPropertyName("output"); - d->notifyObservers(change); - } + d->update(); d->m_outputs.removeOne(output); // Remove bookkeeping connection d->unregisterDestructionHelper(output); diff --git a/tests/auto/render/qrendertarget/tst_qrendertarget.cpp b/tests/auto/render/qrendertarget/tst_qrendertarget.cpp index 03a9e5f94..ffb17faea 100644 --- a/tests/auto/render/qrendertarget/tst_qrendertarget.cpp +++ b/tests/auto/render/qrendertarget/tst_qrendertarget.cpp @@ -167,13 +167,11 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - auto change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "output"); - QCOMPARE(change->addedNodeId(), renderTargetOutput.id()); - QCOMPARE(change->type(), Qt3DCore::PropertyValueAdded); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(arbiter.dirtyNodes.size(), 1); + QCOMPARE(arbiter.dirtyNodes.front(), &renderTarget); - arbiter.events.clear(); + arbiter.dirtyNodes.clear(); } { @@ -182,13 +180,11 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - auto change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "output"); - QCOMPARE(change->removedNodeId(), renderTargetOutput.id()); - QCOMPARE(change->type(), Qt3DCore::PropertyValueRemoved); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(arbiter.dirtyNodes.size(), 1); + QCOMPARE(arbiter.dirtyNodes.front(), &renderTarget); - arbiter.events.clear(); + arbiter.dirtyNodes.clear(); } } }; diff --git a/tests/auto/render/rendertarget/tst_rendertarget.cpp b/tests/auto/render/rendertarget/tst_rendertarget.cpp index a5d8cad77..cd7b0978a 100644 --- a/tests/auto/render/rendertarget/tst_rendertarget.cpp +++ b/tests/auto/render/rendertarget/tst_rendertarget.cpp @@ -75,6 +75,7 @@ private Q_SLOTS: void checkInitializeFromPeer() { // GIVEN + TestRenderer renderer; Qt3DRender::QRenderTarget renderTarget; Qt3DRender::QRenderTargetOutput renderTargetOuput; renderTarget.addOutput(&renderTargetOuput); @@ -82,8 +83,8 @@ private Q_SLOTS: { // WHEN Qt3DRender::Render::RenderTarget backendRenderTarget; - simulateInitialization(&renderTarget, &backendRenderTarget); - + backendRenderTarget.setRenderer(&renderer); + simulateInitializationSync(&renderTarget, &backendRenderTarget); // THEN QCOMPARE(backendRenderTarget.isEnabled(), true); QCOMPARE(backendRenderTarget.peerId(), renderTarget.id()); @@ -93,7 +94,8 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::RenderTarget backendRenderTarget; renderTarget.setEnabled(false); - simulateInitialization(&renderTarget, &backendRenderTarget); + backendRenderTarget.setRenderer(&renderer); + simulateInitializationSync(&renderTarget, &backendRenderTarget); // THEN QCOMPARE(backendRenderTarget.peerId(), renderTarget.id()); @@ -168,17 +170,17 @@ private Q_SLOTS: void checkSceneChangeEvents() { // GIVEN + Qt3DRender::QRenderTarget renderTarget; Qt3DRender::Render::RenderTarget backendRenderTarget; TestRenderer renderer; backendRenderTarget.setRenderer(&renderer); + simulateInitializationSync(&renderTarget, &backendRenderTarget); { // WHEN const bool newValue = false; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("enabled"); - change->setValue(newValue); - backendRenderTarget.sceneChangeEvent(change); + renderTarget.setEnabled(newValue); + backendRenderTarget.syncFromFrontEnd(&renderTarget, false); // THEN QCOMPARE(backendRenderTarget.isEnabled(), newValue); @@ -186,21 +188,23 @@ private Q_SLOTS: { // WHEN Qt3DRender::QRenderTargetOutput targetOutput; - const auto addChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &targetOutput); - addChange->setPropertyName("output"); - backendRenderTarget.sceneChangeEvent(addChange); + renderTarget.addOutput(&targetOutput); + backendRenderTarget.syncFromFrontEnd(&renderTarget, false); // THEN QCOMPARE(backendRenderTarget.renderOutputs().size(), 1); QCOMPARE(backendRenderTarget.renderOutputs().first(), targetOutput.id()); + QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); + renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); // WHEN - const auto removeChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &targetOutput); - removeChange->setPropertyName("output"); - backendRenderTarget.sceneChangeEvent(removeChange); + renderTarget.removeOutput(&targetOutput); + backendRenderTarget.syncFromFrontEnd(&renderTarget, false); // THEN QCOMPARE(backendRenderTarget.renderOutputs().size(), 0); + QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); + renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); } } -- cgit v1.2.3 From 20e42a2c2072ab99588566cd5ee67e0dd4efcc44 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 12:34:03 +0200 Subject: Update QRenderTargetOuput to use direct sync Change-Id: I1ebcd2412a8f7759166bedf88e1c08c8cc816663 Reviewed-by: Paul Lemire --- src/render/backend/rendertargetoutput.cpp | 65 +++++++++++++++---------------- src/render/backend/rendertargetoutput_p.h | 3 +- src/render/frontend/qrenderaspect.cpp | 2 +- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/render/backend/rendertargetoutput.cpp b/src/render/backend/rendertargetoutput.cpp index cba92596d..edfc7132e 100644 --- a/src/render/backend/rendertargetoutput.cpp +++ b/src/render/backend/rendertargetoutput.cpp @@ -55,15 +55,39 @@ RenderTargetOutput::RenderTargetOutput() { } -void RenderTargetOutput::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void RenderTargetOutput::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_attachmentData.m_point = data.attachmentPoint; - m_attachmentData.m_mipLevel = data.mipLevel; - m_attachmentData.m_layer = data.layer; - m_attachmentData.m_face = data.face; - m_attachmentData.m_textureUuid = data.textureId; + const QRenderTargetOutput *node = qobject_cast(frontEnd); + if (!node) + return; + + const bool oldEnabled = isEnabled(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (node->attachmentPoint() != m_attachmentData.m_point) { + m_attachmentData.m_point = node->attachmentPoint(); + markDirty(AbstractRenderer::AllDirty); + } + if (node->mipLevel() != m_attachmentData.m_mipLevel) { + m_attachmentData.m_mipLevel = node->mipLevel(); + markDirty(AbstractRenderer::AllDirty); + } + if (node->layer() != m_attachmentData.m_layer) { + m_attachmentData.m_layer = node->layer(); + markDirty(AbstractRenderer::AllDirty); + } + if (node->face() != m_attachmentData.m_face) { + m_attachmentData.m_face = node->face(); + markDirty(AbstractRenderer::AllDirty); + } + const auto textureId = Qt3DCore::qIdForNode(node->texture()); + if (textureId != m_attachmentData.m_textureUuid) { + m_attachmentData.m_textureUuid = textureId; + markDirty(AbstractRenderer::AllDirty); + } + + if (oldEnabled != isEnabled()) + markDirty(AbstractRenderer::AllDirty); } Qt3DCore::QNodeId RenderTargetOutput::textureUuid() const @@ -96,31 +120,6 @@ QRenderTargetOutput::AttachmentPoint RenderTargetOutput::point() const return m_attachmentData.m_point; } -void RenderTargetOutput::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (e->type() == PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("type")) { - m_attachmentData.m_point = static_cast(propertyChange->value().toInt()); - } - else if (propertyChange->propertyName() == QByteArrayLiteral("texture")) { - m_attachmentData.m_textureUuid = propertyChange->value().value(); - } - else if (propertyChange->propertyName() == QByteArrayLiteral("mipLevel")) { - m_attachmentData.m_mipLevel = propertyChange->value().toInt(); - } - else if (propertyChange->propertyName() == QByteArrayLiteral("layer")) { - m_attachmentData.m_layer = propertyChange->value().toInt(); - } - else if (propertyChange->propertyName() == QByteArrayLiteral("face")) { - m_attachmentData.m_face = static_cast(propertyChange->value().toInt()); - } - markDirty(AbstractRenderer::AllDirty); - } - - BackendNode::sceneChangeEvent(e); -} - Qt3DRender::Render::Attachment *RenderTargetOutput::attachment() { return &m_attachmentData; diff --git a/src/render/backend/rendertargetoutput_p.h b/src/render/backend/rendertargetoutput_p.h index 20476547b..d72f6d231 100644 --- a/src/render/backend/rendertargetoutput_p.h +++ b/src/render/backend/rendertargetoutput_p.h @@ -76,12 +76,11 @@ public: QString name() const; QAbstractTexture::CubeMapFace face() const; QRenderTargetOutput::AttachmentPoint point() const; - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; Attachment *attachment(); const Attachment *attachment() const; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; Qt3DCore::QNodeId m_attachmentUuid; Attachment m_attachmentData; }; diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 1aef960f3..2e90375ae 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -261,7 +261,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); -- cgit v1.2.3 From 6ead5cfc2c7c971a4698e1ebf6b1973b1d8e2a78 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 14:02:21 +0200 Subject: Update QRenderSettings to use direct sync Change-Id: I610d06ac788f839653055a80f78c3f3be5ca68f8 Reviewed-by: Paul Lemire --- src/extras/defaults/qt3dwindow.cpp | 8 +++-- src/render/backend/rendersettings.cpp | 64 ++++++++++++++++----------------- src/render/backend/rendersettings_p.h | 4 +-- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/frontend/qrendersettings.cpp | 11 ++++++ src/render/frontend/qrendersettings.h | 1 + src/render/frontend/qrendersettings_p.h | 2 ++ 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/src/extras/defaults/qt3dwindow.cpp b/src/extras/defaults/qt3dwindow.cpp index a2b9ba4bb..ace40c3c1 100644 --- a/src/extras/defaults/qt3dwindow.cpp +++ b/src/extras/defaults/qt3dwindow.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include @@ -248,8 +249,11 @@ bool Qt3DWindow::event(QEvent *e) { Q_D(Qt3DWindow); const bool needsRedraw = (e->type() == QEvent::Expose || e->type() == QEvent::UpdateRequest); - if (needsRedraw && d->m_renderSettings->renderPolicy() == Qt3DRender::QRenderSettings::OnDemand) - d->m_renderSettings->sendCommand(QLatin1String("InvalidateFrame")); + if (needsRedraw && d->m_renderSettings->renderPolicy() == Qt3DRender::QRenderSettings::OnDemand) { + Qt3DRender::QRenderSettingsPrivate *p = static_cast( + Qt3DCore::QNodePrivate::get(d->m_renderSettings)); + p->invalidateFrame(); + } return QWindow::event(e); } diff --git a/src/render/backend/rendersettings.cpp b/src/render/backend/rendersettings.cpp index 2b8067ce8..702be9c60 100644 --- a/src/render/backend/rendersettings.cpp +++ b/src/render/backend/rendersettings.cpp @@ -63,42 +63,42 @@ RenderSettings::RenderSettings() { } -void RenderSettings::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void RenderSettings::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_activeFrameGraph = data.activeFrameGraphId; - m_renderPolicy = data.renderPolicy; - m_pickMethod = data.pickMethod; - m_pickResultMode = data.pickResultMode; - m_pickWorldSpaceTolerance = data.pickWorldSpaceTolerance; - m_faceOrientationPickingMode = data.faceOrientationPickingMode; -} + const QRenderSettings *node = qobject_cast(frontEnd); + if (!node) + return; -void RenderSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (propertyChange->propertyName() == QByteArrayLiteral("pickMethod")) - m_pickMethod = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("pickResult")) - m_pickResultMode = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("faceOrientationPickingMode")) - m_faceOrientationPickingMode = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("pickWorldSpaceTolerance")) - m_pickWorldSpaceTolerance = propertyChange->value().toFloat(); - else if (propertyChange->propertyName() == QByteArrayLiteral("activeFrameGraph")) - m_activeFrameGraph = propertyChange->value().value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("renderPolicy")) - m_renderPolicy = propertyChange->value().value(); - markDirty(AbstractRenderer::AllDirty); - } else if (e->type() == CommandRequested) { - QNodeCommandPtr command = qSharedPointerCast(e); - if (command->name() == QLatin1String("InvalidateFrame")) - markDirty(AbstractRenderer::AllDirty); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + const Qt3DCore::QNodeId activeFGId = Qt3DCore::qIdForNode(node->activeFrameGraph()); + if (activeFGId != m_activeFrameGraph) { + m_activeFrameGraph = activeFGId; + } + + if (node->renderPolicy() != m_renderPolicy) { + m_renderPolicy = node->renderPolicy(); + } + + if (node->pickingSettings()->pickMethod() != m_pickMethod) { + m_pickMethod = node->pickingSettings()->pickMethod(); + } + + if (node->pickingSettings()->pickResultMode() != m_pickResultMode) { + m_pickResultMode = node->pickingSettings()->pickResultMode(); + } + + if (node->pickingSettings()->worldSpaceTolerance() != m_pickWorldSpaceTolerance) { + m_pickWorldSpaceTolerance = node->pickingSettings()->worldSpaceTolerance(); + } + + if (node->pickingSettings()->faceOrientationPickingMode() != m_faceOrientationPickingMode) { + m_faceOrientationPickingMode = node->pickingSettings()->faceOrientationPickingMode(); } - BackendNode::sceneChangeEvent(e); + // Either because something above as changed or if QRenderSettingsPrivate::invalidFrame() + // was called + markDirty(AbstractRenderer::AllDirty); } RenderSettingsFunctor::RenderSettingsFunctor(AbstractRenderer *renderer) diff --git a/src/render/backend/rendersettings_p.h b/src/render/backend/rendersettings_p.h index d2880c134..1c8c0ca72 100644 --- a/src/render/backend/rendersettings_p.h +++ b/src/render/backend/rendersettings_p.h @@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT RenderSettings : public BackendNode public: RenderSettings(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; Qt3DCore::QNodeId activeFrameGraphID() const { return m_activeFrameGraph; } QRenderSettings::RenderPolicy renderPolicy() const { return m_renderPolicy; } @@ -80,8 +80,6 @@ public: void setActiveFrameGraphId(Qt3DCore::QNodeId frameGraphNodeId) { m_activeFrameGraph = frameGraphNodeId; } private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - QRenderSettings::RenderPolicy m_renderPolicy; QPickingSettings::PickMethod m_pickMethod; QPickingSettings::PickResultMode m_pickResultMode; diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 2e90375ae..afe9cb1df 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -262,7 +262,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->sceneManager())); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer::create(m_renderer)); + q->registerBackendType(QSharedPointer::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); // Geometry + Compute diff --git a/src/render/frontend/qrendersettings.cpp b/src/render/frontend/qrendersettings.cpp index 6ddef6e8a..d106e4205 100644 --- a/src/render/frontend/qrendersettings.cpp +++ b/src/render/frontend/qrendersettings.cpp @@ -96,6 +96,11 @@ void QRenderSettingsPrivate::init() q, SLOT(_q_onWorldSpaceToleranceChanged(float))); } +void QRenderSettingsPrivate::invalidateFrame() +{ + update(); +} + /*! \internal */ void QRenderSettingsPrivate::_q_onPickingMethodChanged(QPickingSettings::PickMethod pickMethod) { @@ -156,6 +161,12 @@ QPickingSettings *QRenderSettings::pickingSettings() return &(d->m_pickingSettings); } +const QPickingSettings *QRenderSettings::pickingSettings() const +{ + Q_D(const QRenderSettings); + return &(d->m_pickingSettings); +} + /*! \qmlproperty FrameGraphNode RenderSettings::activeFrameGraph diff --git a/src/render/frontend/qrendersettings.h b/src/render/frontend/qrendersettings.h index 9d2baa58b..c8771a8fa 100644 --- a/src/render/frontend/qrendersettings.h +++ b/src/render/frontend/qrendersettings.h @@ -71,6 +71,7 @@ public: Q_ENUM(RenderPolicy) // LCOV_EXCL_LINE QPickingSettings* pickingSettings(); + const QPickingSettings* pickingSettings() const; QFrameGraphNode *activeFrameGraph() const; RenderPolicy renderPolicy() const; diff --git a/src/render/frontend/qrendersettings_p.h b/src/render/frontend/qrendersettings_p.h index f91397bd2..88f91810a 100644 --- a/src/render/frontend/qrendersettings_p.h +++ b/src/render/frontend/qrendersettings_p.h @@ -71,6 +71,8 @@ public: QFrameGraphNode *m_activeFrameGraph; QRenderSettings::RenderPolicy m_renderPolicy; + void invalidateFrame(); + void _q_onPickingMethodChanged(QPickingSettings::PickMethod pickMethod); void _q_onPickResultModeChanged(QPickingSettings::PickResultMode pickResultMode); void _q_onFaceOrientationPickingModeChanged(QPickingSettings::FaceOrientationPickingMode faceOrientationPickingMode); -- cgit v1.2.3 From e498e2fc16a09cab315ffaf88eea1679fe2a436d Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 18 Sep 2019 17:18:53 +0200 Subject: Update QRenderState to use direct sync Change-Id: Id38fd035701c86d126851fbde245ebba93e26f34 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/renderstates/genericstate_p.h | 2 +- src/render/renderstates/qstenciloperation.cpp | 13 +- src/render/renderstates/qstenciloperation_p.h | 1 - src/render/renderstates/qstenciltest.cpp | 13 +- src/render/renderstates/qstenciltest_p.h | 1 - src/render/renderstates/renderstatenode.cpp | 156 ++++++++--------- src/render/renderstates/renderstatenode_p.h | 4 +- src/render/renderstates/renderstates.cpp | 193 ++++++++++++--------- src/render/renderstates/renderstates_p.h | 38 ++-- .../auto/render/qrenderstate/tst_qrenderstate.cpp | 20 +-- tests/auto/render/renderpass/tst_renderpass.cpp | 2 + 12 files changed, 216 insertions(+), 229 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index afe9cb1df..575e2c70e 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -263,7 +263,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); // Geometry + Compute q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/src/render/renderstates/genericstate_p.h b/src/render/renderstates/genericstate_p.h index b07487d65..e3ece36f5 100644 --- a/src/render/renderstates/genericstate_p.h +++ b/src/render/renderstates/genericstate_p.h @@ -80,7 +80,7 @@ public: virtual StateMask mask() const = 0; virtual bool equalTo(const RenderStateImpl &renderState) const = 0; - virtual void updateProperty(const char *name, const QVariant &value); + virtual void updateProperties(const QRenderState *); }; template diff --git a/src/render/renderstates/qstenciloperation.cpp b/src/render/renderstates/qstenciloperation.cpp index af7e014f5..86b4c706b 100644 --- a/src/render/renderstates/qstenciloperation.cpp +++ b/src/render/renderstates/qstenciloperation.cpp @@ -106,7 +106,7 @@ QStencilOperation::QStencilOperation(QNode *parent) { Q_D(QStencilOperation); - const auto resend = [d]() { d->resendArguments(); }; + const auto resend = [d]() { d->update(); }; (void) connect(d->m_front, &QStencilOperationArguments::allTestsPassOperationChanged, resend); (void) connect(d->m_front, &QStencilOperationArguments::depthTestFailureOperationChanged, resend); @@ -124,17 +124,6 @@ QStencilOperation::~QStencilOperation() { } -/*! \internal */ -void QStencilOperationPrivate::resendArguments() -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id); - QStencilOperationData data; - fillData(data); - e->setPropertyName("arguments"); - e->setValue(QVariant::fromValue(data)); - notifyObservers(e); -} - /*! \internal */ void QStencilOperationPrivate::fillData(QStencilOperationData &data) const { diff --git a/src/render/renderstates/qstenciloperation_p.h b/src/render/renderstates/qstenciloperation_p.h index a1c0cda4a..d38abf0d7 100644 --- a/src/render/renderstates/qstenciloperation_p.h +++ b/src/render/renderstates/qstenciloperation_p.h @@ -76,7 +76,6 @@ public: QStencilOperationArguments *m_front; QStencilOperationArguments *m_back; - void resendArguments(); void fillData(QStencilOperationData &data) const; }; diff --git a/src/render/renderstates/qstenciltest.cpp b/src/render/renderstates/qstenciltest.cpp index a364c3b88..8f6738e54 100644 --- a/src/render/renderstates/qstenciltest.cpp +++ b/src/render/renderstates/qstenciltest.cpp @@ -109,7 +109,7 @@ QStencilTest::QStencilTest(QNode *parent) { Q_D(QStencilTest); - const auto resend = [d]() { d->resendArguments(); }; + const auto resend = [d]() { d->update(); }; (void) connect(d->m_front, &QStencilTestArguments::comparisonMaskChanged, resend); (void) connect(d->m_front, &QStencilTestArguments::faceModeChanged, resend); @@ -127,17 +127,6 @@ QStencilTest::~QStencilTest() { } -/*! \internal */ -void QStencilTestPrivate::resendArguments() -{ - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id); - QStencilTestData data; - fillData(data); - e->setPropertyName("arguments"); - e->setValue(QVariant::fromValue(data)); - notifyObservers(e); -} - /*! \internal */ void QStencilTestPrivate::fillData(QStencilTestData &data) const { diff --git a/src/render/renderstates/qstenciltest_p.h b/src/render/renderstates/qstenciltest_p.h index 328e34878..9ddfc6e33 100644 --- a/src/render/renderstates/qstenciltest_p.h +++ b/src/render/renderstates/qstenciltest_p.h @@ -78,7 +78,6 @@ public: QStencilTestArguments *m_front; QStencilTestArguments *m_back; - void resendArguments(); void fillData(QStencilTestData &data) const; }; diff --git a/src/render/renderstates/renderstatenode.cpp b/src/render/renderstates/renderstatenode.cpp index f83640154..bd218c803 100644 --- a/src/render/renderstates/renderstatenode.cpp +++ b/src/render/renderstates/renderstatenode.cpp @@ -90,118 +90,105 @@ namespace Render { namespace { -StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChangeBasePtr renderStateChange) +StateVariant createStateImplementation(const QRenderState *node) { - switch (renderStateChange->renderStateType()) { + const QRenderStatePrivate *d = static_cast(Qt3DCore::QNodePrivate::get(node)); + switch (d->m_type) { case AlphaCoverageStateMask: { return StateVariant::createState(); } case AlphaTestMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.alphaFunction, data.referenceValue); + const QAlphaTest *alphaTest = static_cast(node); + return StateVariant::createState(alphaTest->alphaFunction(), alphaTest->referenceValue()); } case BlendStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.blendFunction); + const QBlendEquation *blendEquation = static_cast(node); + return StateVariant::createState(blendEquation->blendFunction()); } case BlendEquationArgumentsMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; + const QBlendEquationArguments *blendArgs = static_cast(node); return StateVariant::createState( - data.sourceRgb, data.destinationRgb, - data.sourceAlpha, data.destinationAlpha, - renderStateChange->isNodeEnabled(), - data.bufferIndex); + blendArgs->sourceRgb(), blendArgs->destinationRgb(), + blendArgs->sourceAlpha(), blendArgs->destinationAlpha(), + blendArgs->isEnabled(), + blendArgs->bufferIndex()); } case MSAAEnabledStateMask: { - return StateVariant::createState(renderStateChange->isNodeEnabled()); + return StateVariant::createState(node->isEnabled()); } case CullFaceStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.mode); + const QCullFace *cullFace = static_cast(node); + return StateVariant::createState(cullFace->mode()); } case DepthRangeMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.nearValue, data.farValue); + const QDepthRange *depthRange = static_cast(node); + return StateVariant::createState(depthRange->nearValue(), depthRange->farValue()); } case DepthWriteStateMask: { - return StateVariant::createState(false); + return StateVariant::createState(!node->isEnabled()); } case DepthTestStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.depthFunction); + const QDepthTest *depthTest = static_cast(node); + return StateVariant::createState(depthTest->depthFunction()); } case RasterModeMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.faceMode, data.rasterMode); + const QRasterMode *rasterMode = static_cast(node); + return StateVariant::createState(rasterMode->faceMode(), rasterMode->rasterMode()); } case FrontFaceStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.direction); + const QFrontFace *frontFace = static_cast(node); + return StateVariant::createState(frontFace->direction()); } case ScissorStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.left, data.bottom, - data.width, data.height); + const QScissorTest *scissorTest = static_cast(node); + return StateVariant::createState(scissorTest->left(), scissorTest->bottom(), + scissorTest->width(), scissorTest->height()); } case StencilTestStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.front.stencilFunction, - data.front.referenceValue, - data.front.comparisonMask, - data.back.stencilFunction, - data.back.referenceValue, - data.back.comparisonMask); + const QStencilTest *stencilTest = static_cast(node); + return StateVariant::createState(stencilTest->front()->stencilFunction(), + stencilTest->front()->referenceValue(), + stencilTest->front()->comparisonMask(), + stencilTest->back()->stencilFunction(), + stencilTest->back()->referenceValue(), + stencilTest->back()->comparisonMask()); } case PointSizeMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - const bool isProgrammable = (data.sizeMode == QPointSize::Programmable); - return StateVariant::createState(isProgrammable, data.value); + const QPointSize *pointSize = static_cast(node); + const bool isProgrammable = (pointSize->sizeMode() == QPointSize::Programmable); + return StateVariant::createState(isProgrammable, pointSize->value()); } case PolygonOffsetStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.scaleFactor, data.depthSteps); + const QPolygonOffset *offset = static_cast(node); + return StateVariant::createState(offset->scaleFactor(), offset->depthSteps()); } case ColorStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.redMasked, data.greenMasked, - data.blueMasked, data.alphaMasked); + const QColorMask *colorMask = static_cast(node); + return StateVariant::createState(colorMask->isRedMasked(), colorMask->isGreenMasked(), + colorMask->isBlueMasked(), colorMask->isAlphaMasked()); } case ClipPlaneMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.planeIndex, - data.normal, - data.distance); + const QClipPlane *clipPlane = static_cast(node); + return StateVariant::createState(clipPlane->planeIndex(), + clipPlane->normal(), + clipPlane->distance()); } case SeamlessCubemapMask: { @@ -209,21 +196,19 @@ StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChan } case StencilOpMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.front.stencilTestFailureOperation, - data.front.depthTestFailureOperation, - data.front.allTestsPassOperation, - data.back.stencilTestFailureOperation, - data.back.depthTestFailureOperation, - data.back.allTestsPassOperation); + const QStencilOperation *stencilOp = static_cast(node); + return StateVariant::createState(stencilOp->front()->stencilTestFailureOperation(), + stencilOp->front()->depthTestFailureOperation(), + stencilOp->front()->allTestsPassOperation(), + stencilOp->back()->stencilTestFailureOperation(), + stencilOp->back()->depthTestFailureOperation(), + stencilOp->back()->allTestsPassOperation()); } case StencilWriteStateMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.frontOutputMask, - data.backOutputMask); + const QStencilMask *stencilMask = static_cast(node); + return StateVariant::createState(stencilMask->frontOutputMask(), + stencilMask->backOutputMask()); } case DitheringStateMask: { @@ -231,9 +216,8 @@ StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChan } case LineWidthMask: { - const auto typedChange = qSharedPointerCast>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState(data.value, data.smooth); + const QLineWidth *lineWidth = static_cast(node); + return StateVariant::createState(lineWidth->value(), lineWidth->smooth()); } default: @@ -258,21 +242,19 @@ void RenderStateNode::cleanup() { } -void RenderStateNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang3) +void RenderStateNode::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - cleanup(); - const auto renderStateChange = qSharedPointerCast(chang3); - m_impl = createStateImplementation(renderStateChange); -} + const QRenderState *node = qobject_cast(frontEnd); + if (!node) + return; -void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == Qt3DCore::PropertyUpdated) { - Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - m_impl.state()->updateProperty(propertyChange->propertyName(), propertyChange->value()); - markDirty(AbstractRenderer::AllDirty); - } - BackendNode::sceneChangeEvent(e); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (firstTime) + m_impl = createStateImplementation(node); + + m_impl.state()->updateProperties(node); + markDirty(AbstractRenderer::AllDirty); } } // namespace Render diff --git a/src/render/renderstates/renderstatenode_p.h b/src/render/renderstates/renderstatenode_p.h index 277b8a7c8..e0258112f 100644 --- a/src/render/renderstates/renderstatenode_p.h +++ b/src/render/renderstates/renderstatenode_p.h @@ -63,8 +63,7 @@ public: RenderStateNode(); virtual ~RenderStateNode(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; - + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; StateMask type() const { return m_impl.type; } StateVariant impl() const { return m_impl; } @@ -72,7 +71,6 @@ protected: void cleanup(); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; StateVariant m_impl; }; diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp index 77143ecd3..bd4a209a1 100644 --- a/src/render/renderstates/renderstates.cpp +++ b/src/render/renderstates/renderstates.cpp @@ -48,152 +48,181 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -void RenderStateImpl::updateProperty(const char *name, const QVariant &value) +void RenderStateImpl::updateProperties(const QRenderState *) { - Q_UNUSED(name); - Q_UNUSED(value); } -void BlendEquationArguments::updateProperty(const char *name, const QVariant &value) +void BlendEquationArguments::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("sourceRgb")) std::get<0>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("destinationRgb")) std::get<1>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("sourceAlpha")) std::get<2>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("destinationAlpha")) std::get<3>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("enabled")) std::get<4>(m_values) = value.toBool(); - else if (name == QByteArrayLiteral("bufferIndex")) std::get<5>(m_values) = value.toInt(); + const QBlendEquationArguments *args = static_cast(node); + + std::get<0>(m_values) = args->sourceRgb(); + std::get<1>(m_values) = args->destinationRgb(); + std::get<2>(m_values) = args->sourceAlpha(); + std::get<3>(m_values) = args->destinationAlpha(); + std::get<4>(m_values) = args->isEnabled(); + std::get<5>(m_values) = args->bufferIndex(); } -void BlendEquation::updateProperty(const char *name, const QVariant &value) +void BlendEquation::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("blendFunction")) std::get<0>(m_values) = value.toInt(); + const QBlendEquation *equation = static_cast(node); + std::get<0>(m_values) = equation->blendFunction(); } -void AlphaFunc::updateProperty(const char *name, const QVariant &value) +void AlphaFunc::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("alphaFunction")) - std::get<0>(m_values) = value.toInt(); - if (name == QByteArrayLiteral("referenceValue")) - std::get<1>(m_values) = value.toFloat(); + const QAlphaTest *alphaTest = static_cast(node); + std::get<0>(m_values) = alphaTest->alphaFunction(); + std::get<1>(m_values) = alphaTest->referenceValue(); } -void MSAAEnabled::updateProperty(const char *name, const QVariant &value) +void MSAAEnabled::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("enabled")) - std::get<0>(m_values) = value.toBool(); + std::get<0>(m_values) = node->isEnabled(); } -void DepthRange::updateProperty(const char *name, const QVariant &value) +void DepthRange::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("nearValue")) std::get<0>(m_values) = value.toDouble(); - else if (name == QByteArrayLiteral("farValue")) std::get<1>(m_values) = value.toDouble(); + const QDepthRange *depthRange = static_cast(node); + + std::get<0>(m_values) = depthRange->nearValue(); + std::get<1>(m_values) = depthRange->farValue(); } -void DepthTest::updateProperty(const char *name, const QVariant &value) +void DepthTest::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("depthFunction")) std::get<0>(m_values) = value.toInt(); + const QDepthTest *depthTest = static_cast(node); + + std::get<0>(m_values) = depthTest->depthFunction(); } -void RasterMode::updateProperty(const char *name, const QVariant &value) +void RasterMode::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("rasterMode")) std::get<0>(m_values) = value.toInt(); - if (name == QByteArrayLiteral("faceMode")) std::get<1>(m_values) = value.toInt(); + const QRasterMode *rasterMode = static_cast(node); + + std::get<0>(m_values) = rasterMode->faceMode(); + std::get<1>(m_values) = rasterMode->rasterMode(); } -void CullFace::updateProperty(const char *name, const QVariant &value) +void CullFace::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("mode")) std::get<0>(m_values) = value.toInt(); + const QCullFace *cullFace = static_cast(node); + + std::get<0>(m_values) = cullFace->mode(); } -void FrontFace::updateProperty(const char *name, const QVariant &value) +void FrontFace::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("direction")) std::get<0>(m_values) = value.toInt(); + const QFrontFace *frontFace = static_cast(node); + + std::get<0>(m_values) = frontFace->direction(); } -void NoDepthMask::updateProperty(const char *name, const QVariant &value) +void NoDepthMask::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("mask")) std::get<0>(m_values) = value.toBool(); + std::get<0>(m_values) = !node->isEnabled(); } -void ScissorTest::updateProperty(const char *name, const QVariant &value) +void ScissorTest::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("left")) std::get<0>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("bottom")) std::get<1>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("width")) std::get<2>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("height")) std::get<3>(m_values) = value.toInt(); + const QScissorTest *scissorTest = static_cast(node); + + std::get<0>(m_values) = scissorTest->left(); + std::get<1>(m_values) = scissorTest->bottom(); + std::get<2>(m_values) = scissorTest->width(); + std::get<3>(m_values) = scissorTest->height(); } -void StencilTest::updateProperty(const char *name, const QVariant &value) +void StencilTest::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("arguments")) { - const QStencilTestData data = value.value(); - std::get<0>(m_values) = data.front.stencilFunction; - std::get<1>(m_values) = data.front.referenceValue; - std::get<2>(m_values) = data.front.comparisonMask; - std::get<3>(m_values) = data.back.stencilFunction; - std::get<4>(m_values) = data.back.referenceValue; - std::get<5>(m_values) = data.back.comparisonMask; - } + const QStencilTest *stencilTest = static_cast(node); + std::get<0>(m_values) = stencilTest->front()->stencilFunction(); + std::get<1>(m_values) = stencilTest->front()->referenceValue(); + std::get<2>(m_values) = stencilTest->front()->comparisonMask(); + std::get<3>(m_values) = stencilTest->back()->stencilFunction(); + std::get<4>(m_values) = stencilTest->back()->referenceValue(); + std::get<5>(m_values) = stencilTest->back()->comparisonMask(); } -void PointSize::updateProperty(const char *name, const QVariant &value) +void PointSize::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("sizeMode")) std::get<0>(m_values) = (value.toInt() == QPointSize::Programmable); - else if (name == QByteArrayLiteral("value")) std::get<1>(m_values) = value.toFloat(); + const QPointSize *pointSize = static_cast(node); + + std::get<0>(m_values) = (pointSize->sizeMode() == QPointSize::Programmable); + std::get<1>(m_values) = pointSize->value(); } -void PolygonOffset::updateProperty(const char *name, const QVariant &value) +void PolygonOffset::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("scaleFactor")) std::get<0>(m_values) = value.toFloat(); - else if (name == QByteArrayLiteral("depthSteps")) std::get<1>(m_values) = value.toFloat(); + const QPolygonOffset *offset = static_cast(node); + + std::get<0>(m_values) = offset->scaleFactor(); + std::get<1>(m_values) = offset->depthSteps(); } -void ColorMask::updateProperty(const char *name, const QVariant &value) +void ColorMask::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("redMasked")) std::get<0>(m_values) = value.toBool(); - else if (name == QByteArrayLiteral("greenMasked")) std::get<1>(m_values) = value.toBool(); - else if (name == QByteArrayLiteral("blueMasked")) std::get<2>(m_values) = value.toBool(); - else if (name == QByteArrayLiteral("alphaMasked")) std::get<3>(m_values) = value.toBool(); + const QColorMask *colorMask = static_cast(node); + + std::get<0>(m_values) = colorMask->isRedMasked(); + std::get<1>(m_values) = colorMask->isGreenMasked(); + std::get<2>(m_values) = colorMask->isBlueMasked(); + std::get<3>(m_values) = colorMask->isAlphaMasked(); } -void ClipPlane::updateProperty(const char *name, const QVariant &value) +void ClipPlane::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("planeIndex")) std::get<0>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("normal")) std::get<1>(m_values) = value.value(); - else if (name == QByteArrayLiteral("distance")) std::get<2>(m_values) = value.toFloat(); + const QClipPlane *clipPlane = static_cast(node); + + std::get<0>(m_values) = clipPlane->planeIndex(); + std::get<1>(m_values) = clipPlane->normal(); + std::get<2>(m_values) = clipPlane->distance(); } -void StencilOp::updateProperty(const char *name, const QVariant &value) +void StencilOp::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("arguments")) { - const QStencilOperationData data = value.value(); - std::get<0>(m_values) = data.front.stencilTestFailureOperation; - std::get<1>(m_values) = data.front.depthTestFailureOperation; - std::get<2>(m_values) = data.front.allTestsPassOperation; - std::get<3>(m_values) = data.back.stencilTestFailureOperation; - std::get<4>(m_values) = data.back.depthTestFailureOperation; - std::get<5>(m_values) = data.back.allTestsPassOperation; - } + const QStencilOperation *stencilOp = static_cast(node); + + std::get<0>(m_values) = stencilOp->front()->stencilTestFailureOperation(); + std::get<1>(m_values) = stencilOp->front()->depthTestFailureOperation(); + std::get<2>(m_values) = stencilOp->front()->allTestsPassOperation(); + std::get<3>(m_values) = stencilOp->back()->stencilTestFailureOperation(); + std::get<4>(m_values) = stencilOp->back()->depthTestFailureOperation(); + std::get<5>(m_values) = stencilOp->back()->allTestsPassOperation(); } -void StencilMask::updateProperty(const char *name, const QVariant &value) +void StencilMask::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("frontOutputMask")) std::get<0>(m_values) = value.toInt(); - else if (name == QByteArrayLiteral("backOutputMask")) std::get<1>(m_values) = value.toInt(); + const QStencilMask *stencilMask = static_cast(node); + std::get<0>(m_values) = stencilMask->frontOutputMask(); + std::get<1>(m_values) = stencilMask->backOutputMask(); } -void LineWidth::updateProperty(const char *name, const QVariant &value) +void LineWidth::updateProperties(const QRenderState *node) { - if (name == QByteArrayLiteral("value")) - std::get<0>(m_values) = value.toFloat(); - else if (name == QByteArrayLiteral("smooth")) - std::get<1>(m_values) = value.toBool(); + const QLineWidth *lineWidth = static_cast(node); + std::get<0>(m_values) = lineWidth->value(); + std::get<1>(m_values) = lineWidth->smooth(); } } // namespace Render diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h index 7c6dc4ebd..6c8e9d551 100644 --- a/src/render/renderstates/renderstates_p.h +++ b/src/render/renderstates/renderstates_p.h @@ -62,61 +62,61 @@ namespace Render { class Q_AUTOTEST_EXPORT BlendEquationArguments : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT BlendEquation : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT MSAAEnabled : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT DepthRange : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT DepthTest : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT RasterMode : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT NoDepthMask : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT CullFace : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT FrontFace : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT Dithering : public GenericState @@ -126,13 +126,13 @@ class Q_AUTOTEST_EXPORT Dithering : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT StencilTest : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState @@ -142,26 +142,26 @@ class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT ColorMask : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT ClipPlane : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState @@ -171,19 +171,19 @@ class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT StencilMask : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT LineWidth : public GenericState { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; } // namespace Render diff --git a/tests/auto/render/qrenderstate/tst_qrenderstate.cpp b/tests/auto/render/qrenderstate/tst_qrenderstate.cpp index 63319b42c..fb212bc8f 100644 --- a/tests/auto/render/qrenderstate/tst_qrenderstate.cpp +++ b/tests/auto/render/qrenderstate/tst_qrenderstate.cpp @@ -75,8 +75,8 @@ private: RenderStateNode* createBackendNode(QRenderState *frontend) { RenderStateNode *backend = m_renderStateManager.getOrCreateResource(frontend->id()); - simulateInitialization(frontend, backend); backend->setRenderer(&m_renderer); + simulateInitializationSync(frontend, backend); return backend; } @@ -187,6 +187,7 @@ private Q_SLOTS: // THEN RenderStateNode *backend1 = createBackendNode(frontend1); RenderStateNode *backend2 = createBackendNode(frontend2); + QVERIFY(backend1->type() == mask); QVERIFY(backend2->type() == mask); QVERIFY(backend1->impl() != backend2->impl()); @@ -204,12 +205,11 @@ private Q_SLOTS: QCOMPARE(arbiter.dirtyNodes.size(), 1); QCOMPARE(arbiter.dirtyNodes.front(), frontend1); - // TODOSYNC update when syncFromFrontendNode is implemented -// // WHEN -// backend1->sceneChangeEvent(change.staticCast()); + // WHEN + backend1->syncFromFrontEnd(frontend1, false); -// // THEN -// QVERIFY(backend1->impl() == backend2->impl()); + // THEN + QVERIFY(backend1->impl() == backend2->impl()); arbiter.dirtyNodes.clear(); } @@ -285,12 +285,12 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast(); - QCOMPARE(change->subjectId(), frontend1->id()); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(arbiter.dirtyNodes.size(), 1); + QCOMPARE(arbiter.dirtyNodes.front(), frontend1); // WHEN - backend1->sceneChangeEvent(change.staticCast()); + backend1->syncFromFrontEnd(frontend1, false); // THEN QVERIFY(backend1->impl() == backend2->impl()); diff --git a/tests/auto/render/renderpass/tst_renderpass.cpp b/tests/auto/render/renderpass/tst_renderpass.cpp index 7be741936..136e2755d 100644 --- a/tests/auto/render/renderpass/tst_renderpass.cpp +++ b/tests/auto/render/renderpass/tst_renderpass.cpp @@ -148,6 +148,7 @@ private slots: backend.setRenderer(&renderer); RenderStateNode *backendState = m_renderStateManager->getOrCreateResource(frontendState->id()); + backendState->setRenderer(&renderer); simulateInitializationSync(frontendState, backendState); // WHEN @@ -262,6 +263,7 @@ private slots: backend.setRenderer(&renderer); RenderStateNode *backendState = m_renderStateManager->getOrCreateResource(frontendState->id()); + backendState->setRenderer(&renderer); simulateInitializationSync(frontendState, backendState); QRenderPass frontend; -- cgit v1.2.3 From cca7720e68a3bf64dbf549b06ba13547cb29181c Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 09:57:53 +0200 Subject: Update QComputeCommand to use direct sync Change-Id: I5e755bbc7e3a948f7f2356d7110ac817ae32616a Reviewed-by: Mike Krus --- src/render/backend/computecommand.cpp | 50 +++++++++++----------- src/render/backend/computecommand_p.h | 3 +- src/render/frontend/qcomputecommand.cpp | 5 +-- src/render/frontend/qrenderaspect.cpp | 2 +- .../render/computecommand/tst_computecommand.cpp | 44 ++++++++----------- .../render/qcomputecommand/tst_qcomputecommand.cpp | 25 ++--------- 6 files changed, 48 insertions(+), 81 deletions(-) diff --git a/src/render/backend/computecommand.cpp b/src/render/backend/computecommand.cpp index 7079d0308..386c25fec 100644 --- a/src/render/backend/computecommand.cpp +++ b/src/render/backend/computecommand.cpp @@ -73,35 +73,35 @@ void ComputeCommand::cleanup() m_runType = QComputeCommand::Continuous; } -void ComputeCommand::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void ComputeCommand::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_workGroups[0] = data.workGroupX; - m_workGroups[1] = data.workGroupY; - m_workGroups[2] = data.workGroupZ; - m_runType = data.runType; - m_frameCount = data.frameCount; - markDirty(AbstractRenderer::ComputeDirty); -} + const QComputeCommand *node = qobject_cast(frontEnd); + if (!node) + return; -void ComputeCommand::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (e->type() == Qt3DCore::PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("workGroupX")) - m_workGroups[0] = propertyChange->value().toInt(); - else if (propertyChange->propertyName() == QByteArrayLiteral("workGroupY")) - m_workGroups[1] = propertyChange->value().toInt(); - else if (propertyChange->propertyName() == QByteArrayLiteral("workGroupZ")) - m_workGroups[2] = propertyChange->value().toInt(); - else if (propertyChange->propertyName() == QByteArrayLiteral("frameCount")) - m_frameCount = propertyChange->value().toInt(); - else if (propertyChange->propertyName() == QByteArrayLiteral("runType")) - m_runType = static_cast(propertyChange->value().toInt()); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (m_workGroups[0] != node->workGroupX()) { + m_workGroups[0] = node->workGroupX(); + markDirty(AbstractRenderer::ComputeDirty); + } + if (m_workGroups[1] != node->workGroupY()) { + m_workGroups[1] = node->workGroupY(); + markDirty(AbstractRenderer::ComputeDirty); + } + if (m_workGroups[2] != node->workGroupZ()) { + m_workGroups[2] = node->workGroupZ(); + markDirty(AbstractRenderer::ComputeDirty); + } + if (node->runType() != m_runType) { + m_runType = node->runType(); + markDirty(AbstractRenderer::ComputeDirty); + } + const QComputeCommandPrivate *d = static_cast(Qt3DCore::QNodePrivate::get(node)); + if (d->m_frameCount != m_frameCount) { + m_frameCount = d->m_frameCount; markDirty(AbstractRenderer::ComputeDirty); } - BackendNode::sceneChangeEvent(e); } // Called from buildComputeRenderCommands in a job diff --git a/src/render/backend/computecommand_p.h b/src/render/backend/computecommand_p.h index 10e10fd25..dc2069928 100644 --- a/src/render/backend/computecommand_p.h +++ b/src/render/backend/computecommand_p.h @@ -69,7 +69,7 @@ public: ~ComputeCommand(); void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; inline int x() const Q_DECL_NOTHROW { return m_workGroups[0]; } inline int y() const Q_DECL_NOTHROW { return m_workGroups[1]; } @@ -81,7 +81,6 @@ public: void updateFrameCount(); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; int m_workGroups[3]; int m_frameCount; QComputeCommand::RunType m_runType; diff --git a/src/render/frontend/qcomputecommand.cpp b/src/render/frontend/qcomputecommand.cpp index 8b176cd4f..b0bec42d4 100644 --- a/src/render/frontend/qcomputecommand.cpp +++ b/src/render/frontend/qcomputecommand.cpp @@ -156,10 +156,7 @@ QComputeCommandPrivate::QComputeCommandPrivate() void QComputeCommandPrivate::setFrameCount(int frameCount) { m_frameCount = frameCount; - const auto propertyChange = Qt3DCore::QPropertyUpdatedChangePtr::create(m_id); - propertyChange->setPropertyName("frameCount"); - propertyChange->setValue(m_frameCount); - notifyObservers(propertyChange); + update(); } /*! diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 575e2c70e..c83b5cb69 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -268,7 +268,7 @@ void QRenderAspectPrivate::registerBackendTypes() // Geometry + Compute q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->bufferManager())); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->geometryRendererManager())); q->registerBackendType(QSharedPointer>::create(m_renderer)); diff --git a/tests/auto/render/computecommand/tst_computecommand.cpp b/tests/auto/render/computecommand/tst_computecommand.cpp index a82c3eeaf..990c0cd98 100644 --- a/tests/auto/render/computecommand/tst_computecommand.cpp +++ b/tests/auto/render/computecommand/tst_computecommand.cpp @@ -87,7 +87,7 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::ComputeCommand backendComputeCommand; backendComputeCommand.setRenderer(&renderer); - simulateInitialization(&computeCommand, &backendComputeCommand); + simulateInitializationSync(&computeCommand, &backendComputeCommand); // THEN QCOMPARE(backendComputeCommand.isEnabled(), true); @@ -105,7 +105,7 @@ private Q_SLOTS: Qt3DRender::Render::ComputeCommand backendComputeCommand; backendComputeCommand.setRenderer(&renderer); computeCommand.setEnabled(false); - simulateInitialization(&computeCommand, &backendComputeCommand); + simulateInitializationSync(&computeCommand, &backendComputeCommand); // THEN QCOMPARE(backendComputeCommand.peerId(), computeCommand.id()); @@ -118,16 +118,16 @@ private Q_SLOTS: { // GIVEN Qt3DRender::Render::ComputeCommand backendComputeCommand; + Qt3DRender::QComputeCommand computeCommand; TestRenderer renderer; backendComputeCommand.setRenderer(&renderer); + simulateInitializationSync(&computeCommand, &backendComputeCommand); { // WHEN const bool newValue = false; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("enabled"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.setEnabled(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.isEnabled(), newValue); @@ -135,10 +135,8 @@ private Q_SLOTS: { // WHEN const int newValue = 128; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("workGroupX"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.setWorkGroupX(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.x(), newValue); @@ -146,10 +144,8 @@ private Q_SLOTS: { // WHEN const int newValue = 64; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("workGroupY"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.setWorkGroupY(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.y(), newValue); @@ -157,10 +153,8 @@ private Q_SLOTS: { // WHEN const int newValue = 32; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("workGroupZ"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.setWorkGroupZ(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.z(), newValue); @@ -168,10 +162,8 @@ private Q_SLOTS: { // WHEN const Qt3DRender::QComputeCommand::RunType newValue = Qt3DRender::QComputeCommand::Manual; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("runType"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.setRunType(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.runType(), newValue); @@ -179,10 +171,8 @@ private Q_SLOTS: { // WHEN const int newValue = 32; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("frameCount"); - change->setValue(newValue); - backendComputeCommand.sceneChangeEvent(change); + computeCommand.trigger(newValue); + backendComputeCommand.syncFromFrontEnd(&computeCommand, false); // THEN QCOMPARE(backendComputeCommand.frameCount(), newValue); @@ -208,7 +198,7 @@ private Q_SLOTS: Qt3DCore::QBackendNodePrivate::get(&backendComputeCommand)->setArbiter(&arbiter); backendComputeCommand.setRenderer(&renderer); - simulateInitialization(&computeCommand, &backendComputeCommand); + simulateInitializationSync(&computeCommand, &backendComputeCommand); for (int i = 0; i < 5; ++i) { // WHEN diff --git a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp index b46cc4ea0..4494e773b 100644 --- a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp +++ b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp @@ -342,13 +342,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - { - auto change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value(), 1); - QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); - } + QCOMPARE(arbiter.events.size(), 0); QCOMPARE(arbiter.dirtyNodes.size(), 1); QCOMPARE(arbiter.dirtyNodes.front(), &computeCommand); QCOMPARE(computeCommand.isEnabled(), true); @@ -356,7 +350,6 @@ private Q_SLOTS: computeCommand.setEnabled(false); QCoreApplication::processEvents(); arbiter.dirtyNodes.clear(); - arbiter.events.clear(); } { @@ -365,13 +358,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - { - auto change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value(), 2); - QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); - } + QCOMPARE(arbiter.events.size(), 0); QCOMPARE(arbiter.dirtyNodes.size(), 1); QCOMPARE(arbiter.dirtyNodes.front(), &computeCommand); QCOMPARE(computeCommand.isEnabled(), true); @@ -388,13 +375,7 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - { - auto change = arbiter.events.at(0).staticCast(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value(), 1); - QCOMPARE(change->type(), Qt3DCore::PropertyUpdated); - } + QCOMPARE(arbiter.events.size(), 0); QCOMPARE(arbiter.dirtyNodes.size(), 1); QCOMPARE(arbiter.dirtyNodes.front(), &computeCommand); QCOMPARE(computeCommand.isEnabled(), true); -- cgit v1.2.3 From 81ba7578c9fa9781f5996aa8bf249ff8abdd1f9f Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 12:26:49 +0200 Subject: Update QAbstractTextureImage to use direct sync Change-Id: Ide55f36fc7e1ac197313307a1c3e58c06ac690a1 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/texture/qabstracttextureimage.cpp | 6 ++ src/render/texture/qabstracttextureimage_p.h | 2 + src/render/texture/textureimage.cpp | 53 +++++----- src/render/texture/textureimage_p.h | 4 +- tests/auto/render/textures/tst_textures.cpp | 147 ++++++++++++++------------- 6 files changed, 113 insertions(+), 101 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index c83b5cb69..de27eb84f 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -277,7 +277,7 @@ void QRenderAspectPrivate::registerBackendTypes() // Textures q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->textureManager())); - q->registerBackendType(QSharedPointer::create(m_renderer, + q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers->textureImageManager())); // Material system diff --git a/src/render/texture/qabstracttextureimage.cpp b/src/render/texture/qabstracttextureimage.cpp index 42f8eb747..a5d342d83 100644 --- a/src/render/texture/qabstracttextureimage.cpp +++ b/src/render/texture/qabstracttextureimage.cpp @@ -94,6 +94,12 @@ QAbstractTextureImagePrivate::~QAbstractTextureImagePrivate() { } +QTextureImageDataGeneratorPtr QAbstractTextureImagePrivate::dataGenerator() const +{ + Q_Q(const QAbstractTextureImage); + return q->dataGenerator(); +} + /*! \qmltype AbstractTextureImage \instantiates Qt3DRender::QAbstractTextureImage diff --git a/src/render/texture/qabstracttextureimage_p.h b/src/render/texture/qabstracttextureimage_p.h index a5299acd7..f93d0e3ca 100644 --- a/src/render/texture/qabstracttextureimage_p.h +++ b/src/render/texture/qabstracttextureimage_p.h @@ -54,6 +54,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -72,6 +73,7 @@ public: int m_mipLevel; int m_layer; QAbstractTexture::CubeMapFace m_face; + QTextureImageDataGeneratorPtr dataGenerator() const; }; struct QAbstractTextureImageData diff --git a/src/render/texture/textureimage.cpp b/src/render/texture/textureimage.cpp index 87cfdbca6..512949d91 100644 --- a/src/render/texture/textureimage.cpp +++ b/src/render/texture/textureimage.cpp @@ -72,36 +72,39 @@ void TextureImage::cleanup() m_face = QAbstractTexture::CubeMapPositiveX; } -void TextureImage::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void TextureImage::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_mipLevel = data.mipLevel; - m_layer = data.layer; - m_face = data.face; - m_generator = data.generator; - m_dirty = true; -} + const QAbstractTextureImage *node = qobject_cast(frontEnd); + if (!node) + return; -void TextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - - if (e->type() == PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("layer")) { - m_layer = propertyChange->value().toInt(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("mipLevel")) { - m_mipLevel = propertyChange->value().toInt(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("face")) { - m_face = static_cast(propertyChange->value().toInt()); - } else if (propertyChange->propertyName() == QByteArrayLiteral("dataGenerator")) { - m_generator = propertyChange->value().value(); - } + const bool oldEnabled = isEnabled(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + m_dirty |= (oldEnabled != isEnabled()); + + if (node->layer() != m_layer) { + m_layer = node->layer(); + m_dirty = true; + } + + if (node->mipLevel() != m_mipLevel) { + m_mipLevel = node->mipLevel(); + m_dirty = true; + } + + if (node->face() != m_face) { + m_face = node->face(); + m_dirty = true; + } + + const QAbstractTextureImagePrivate *d = static_cast(QNodePrivate::get(node)); + if (d->dataGenerator() != m_generator) { + m_generator = d->dataGenerator(); m_dirty = true; } - markDirty(AbstractRenderer::AllDirty); - BackendNode::sceneChangeEvent(e); + if (m_dirty) + markDirty(AbstractRenderer::AllDirty); } void TextureImage::unsetDirty() diff --git a/src/render/texture/textureimage_p.h b/src/render/texture/textureimage_p.h index 490fe4432..57bbdea75 100644 --- a/src/render/texture/textureimage_p.h +++ b/src/render/texture/textureimage_p.h @@ -77,7 +77,7 @@ public: ~TextureImage(); void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; inline int layer() const { return m_layer; } inline int mipLevel() const { return m_mipLevel; } @@ -87,8 +87,6 @@ public: void unsetDirty(); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - bool m_dirty; int m_layer; int m_mipLevel; diff --git a/tests/auto/render/textures/tst_textures.cpp b/tests/auto/render/textures/tst_textures.cpp index 1cd11b153..725ddc269 100644 --- a/tests/auto/render/textures/tst_textures.cpp +++ b/tests/auto/render/textures/tst_textures.cpp @@ -141,6 +141,11 @@ public: { } + void updateGenerator() + { + Qt3DRender::QAbstractTextureImage::notifyDataGeneratorChanged(); + } + Qt3DRender::QTextureImageDataGeneratorPtr dataGenerator() const { return Qt3DRender::QTextureImageDataGeneratorPtr(new TestImageDataGenerator(m_genId)); @@ -187,17 +192,20 @@ class tst_RenderTextures : public Qt3DCore::QBackendNodeTester Qt3DRender::Render::Texture *createBackendTexture(Qt3DRender::QAbstractTexture *frontend, Qt3DRender::Render::TextureManager *texMgr, - Qt3DRender::Render::TextureImageManager *texImgMgr) + Qt3DRender::Render::TextureImageManager *texImgMgr, + Qt3DRender::Render::AbstractRenderer *renderer) { Qt3DRender::Render::Texture *backend = texMgr->getOrCreateResource(frontend->id()); - simulateInitialization(frontend, backend); + backend->setRenderer(renderer); + simulateInitializationSync(frontend, backend); // create texture images for (const auto texImgFrontend : frontend->textureImages()) { // make sure TextureImageManager has backend node for this QTextureImage if (!texImgMgr->contains(texImgFrontend->id())) { Qt3DRender::Render::TextureImage *texImgBackend = texImgMgr->getOrCreateResource(texImgFrontend->id()); - simulateInitialization(texImgFrontend, texImgBackend); + texImgBackend->setRenderer(renderer); + simulateInitializationSync(texImgFrontend, texImgBackend); } backend->addTextureImage(texImgFrontend->id()); } @@ -221,10 +229,12 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1a = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); Qt3DRender::Render::Texture *bt1b = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); renderer.updateTexture(bt1a); renderer.updateTexture(bt1b); @@ -254,7 +264,8 @@ private Q_SLOTS: for (auto *t : textures) { Qt3DRender::Render::Texture *backendTexture = createBackendTexture(t, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); backend.push_back(backendTexture); renderer.updateTexture(backendTexture); } @@ -303,10 +314,12 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); // THEN QCOMPARE(bt1->sharedTextureId(), 1); QCOMPARE(bt2->sharedTextureId(), 1); @@ -332,10 +345,12 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::Texture *bt1 = createBackendTexture(tex1a, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); Qt3DRender::Render::Texture *bt2 = createBackendTexture(tex1b, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); // THEN QCOMPARE(bt1->sharedTextureId(), 1); QCOMPARE(bt2->sharedTextureId(), 2); @@ -372,7 +387,8 @@ private Q_SLOTS: for (auto *t : textures) { Qt3DRender::Render::Texture *backendTexture = createBackendTexture(t, mgrs->textureManager(), - mgrs->textureImageManager()); + mgrs->textureImageManager(), + &renderer); backend.push_back(backendTexture); renderer.updateTexture(backendTexture); } @@ -416,13 +432,15 @@ private Q_SLOTS: void checkTextureImageCleanupState() { // GIVEN + Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous); TestTextureImage img(1); img.setLayer(2); img.setMipLevel(3); // WHEN Qt3DRender::Render::TextureImage texImgBackend; - simulateInitialization(&img, &texImgBackend); + texImgBackend.setRenderer(&renderer); + simulateInitializationSync(&img, &texImgBackend); texImgBackend.cleanup(); // THEN @@ -431,11 +449,14 @@ private Q_SLOTS: QCOMPARE(texImgBackend.mipLevel(), 0); QCOMPARE(texImgBackend.face(), Qt3DRender::QAbstractTexture::CubeMapPositiveX); QVERIFY(texImgBackend.dataGenerator().isNull()); + + renderer.shutdown(); } void checkTextureImageInitializeFromPeer() { // GIVEN + Qt3DRender::Render::Renderer renderer(Qt3DRender::QRenderAspect::Synchronous); TestTextureImage img(1); { @@ -444,7 +465,8 @@ private Q_SLOTS: img.setMipLevel(3); Qt3DRender::Render::TextureImage texImgBackend; - simulateInitialization(&img, &texImgBackend); + texImgBackend.setRenderer(&renderer); + simulateInitializationSync(&img, &texImgBackend); // THEN QCOMPARE(texImgBackend.isEnabled(), true); @@ -461,28 +483,31 @@ private Q_SLOTS: img.setEnabled(false); Qt3DRender::Render::TextureImage texImgBackend; - simulateInitialization(&img, &texImgBackend); + texImgBackend.setRenderer(&renderer); + simulateInitializationSync(&img, &texImgBackend); // THEN QCOMPARE(texImgBackend.isEnabled(), false); QCOMPARE(texImgBackend.peerId(), img.id()); } + + renderer.shutdown(); } void checkTextureImageSceneChangeEvents() { // GIVEN Qt3DRender::Render::TextureImage backendImage; + TestTextureImage textureImage(1); TestRenderer renderer; backendImage.setRenderer(&renderer); + simulateInitializationSync(&textureImage, &backendImage); { // WHEN const bool newValue = false; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("enabled"); - change->setValue(newValue); - backendImage.sceneChangeEvent(change); + textureImage.setEnabled(newValue); + backendImage.syncFromFrontEnd(&textureImage, false); // THEN QCOMPARE(backendImage.isEnabled(), newValue); @@ -495,10 +520,8 @@ private Q_SLOTS: { // WHEN const int newValue = 7; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("layer"); - change->setValue(newValue); - backendImage.sceneChangeEvent(change); + textureImage.setLayer(newValue); + backendImage.syncFromFrontEnd(&textureImage, false); // THEN QCOMPARE(backendImage.layer(), newValue); @@ -511,10 +534,9 @@ private Q_SLOTS: { // WHEN const int newValue = 3; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("mipLevel"); - change->setValue(newValue); - backendImage.sceneChangeEvent(change); + textureImage.setMipLevel(newValue); + backendImage.syncFromFrontEnd(&textureImage, false); + // THEN QCOMPARE(backendImage.mipLevel(), newValue); @@ -527,10 +549,8 @@ private Q_SLOTS: { // WHEN const Qt3DRender::QAbstractTexture::CubeMapFace newValue = Qt3DRender::QAbstractTexture::CubeMapNegativeX; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("face"); - change->setValue(newValue); - backendImage.sceneChangeEvent(change); + textureImage.setFace(newValue); + backendImage.syncFromFrontEnd(&textureImage, false); // THEN QCOMPARE(backendImage.face(), newValue); @@ -542,45 +562,24 @@ private Q_SLOTS: { // WHEN - Qt3DRender::QTextureImageDataGeneratorPtr generator1(new TestImageDataGenerator(883)); - auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("dataGenerator"); - change->setValue(QVariant::fromValue(generator1)); - backendImage.sceneChangeEvent(change); + textureImage.updateGenerator(); + backendImage.syncFromFrontEnd(&textureImage, false); // THEN - QCOMPARE(backendImage.dataGenerator(), generator1); QVERIFY(backendImage.isDirty()); QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); backendImage.unsetDirty(); // WHEN - Qt3DRender::QTextureImageDataGeneratorPtr generator2(new TestImageDataGenerator(1584)); - change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("dataGenerator"); - change->setValue(QVariant::fromValue(generator2)); - backendImage.sceneChangeEvent(change); + textureImage.updateGenerator(); + backendImage.syncFromFrontEnd(&textureImage, false); // THEN QVERIFY(backendImage.isDirty()); QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); backendImage.unsetDirty(); - - // WHEN - Qt3DRender::QTextureImageDataGeneratorPtr generator3; - change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("dataGenerator"); - change->setValue(QVariant::fromValue(generator3)); - backendImage.sceneChangeEvent(change); - - // THEN - QVERIFY(backendImage.dataGenerator().isNull()); - QVERIFY(backendImage.isDirty()); - QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::AllDirty); - renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); - backendImage.unsetDirty(); } renderer.shutdown(); @@ -598,7 +597,8 @@ private Q_SLOTS: Qt3DRender::QAbstractTexture* frontendTexture = createQTexture(1, {1}, true); Qt3DRender::Render::Texture *backendTexture = texMgr->getOrCreateResource(frontendTexture->id()); - simulateInitialization(frontendTexture, backendTexture); + backendTexture->setRenderer(&renderer); + simulateInitializationSync(frontendTexture, backendTexture); // THEN QCOMPARE(backendTexture->textureImageIds().size(), 1); @@ -613,7 +613,8 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::TextureImage *texImgBackend = texImgMgr->getOrCreateResource(texImgFrontend->id()); - simulateInitialization(texImgFrontend, texImgBackend); + texImgBackend->setRenderer(&renderer); + simulateInitializationSync(texImgFrontend, texImgBackend); // THEN qDebug() << frontendGenerator << texImgBackend->dataGenerator(); @@ -638,7 +639,8 @@ private Q_SLOTS: Qt3DRender::QAbstractTexture* frontendTexture = createQTexture(1, {1}, true); Qt3DRender::Render::Texture *backendTexture = static_cast(textureBackendNodeMapper.create(creationChange(frontendTexture))); - simulateInitialization(frontendTexture, backendTexture); + backendTexture->setRenderer(&renderer); + simulateInitializationSync(frontendTexture, backendTexture); // THEN QVERIFY(backendTexture != nullptr); @@ -671,7 +673,8 @@ private Q_SLOTS: Qt3DRender::QAbstractTexture* frontendTexture = createQTexture(1, {1}, true); Qt3DRender::Render::Texture *backendTexture = static_cast(textureBackendNodeMapper.create(creationChange(frontendTexture))); - simulateInitialization(frontendTexture, backendTexture); + backendTexture->setRenderer(&renderer); + simulateInitializationSync(frontendTexture, backendTexture); // WHEN textureBackendNodeMapper.destroy(frontendTexture->id()); @@ -683,7 +686,8 @@ private Q_SLOTS: // WHEN backendTexture = static_cast(textureBackendNodeMapper.create(creationChange(frontendTexture))); - simulateInitialization(frontendTexture, backendTexture); + backendTexture->setRenderer(&renderer); + simulateInitializationSync(frontendTexture, backendTexture); // THEN QVERIFY(backendTexture != nullptr); @@ -703,10 +707,10 @@ private Q_SLOTS: renderer.setNodeManagers(mgrs.data()); Qt3DRender::QTexture2D *texture1 = new Qt3DRender::QTexture2D(); - Qt3DRender::QAbstractTextureImage *image1 = new EmptyTextureImage(); + TestTextureImage *image1 = new TestTextureImage(1); Qt3DRender::QTexture2D *texture2 = new Qt3DRender::QTexture2D(); - Qt3DRender::QAbstractTextureImage *image2 = new EmptyTextureImage(); + TestTextureImage *image2 = new TestTextureImage(2); Qt3DRender::QTexture2D *texture3 = new Qt3DRender::QTexture2D(); @@ -721,18 +725,17 @@ private Q_SLOTS: Qt3DRender::Render::TextureImage *backendImage1 = texImgMgr->getOrCreateResource(image1->id()); Qt3DRender::Render::TextureImage *backendImage2 = texImgMgr->getOrCreateResource(image2->id()); - simulateInitialization(texture1, backendTexture1); - simulateInitialization(texture2, backendTexture2); - simulateInitialization(texture3, backendTexture3); - simulateInitialization(image1, backendImage1); - simulateInitialization(image2, backendImage2); - backendTexture1->setRenderer(&renderer); backendTexture2->setRenderer(&renderer); backendTexture3->setRenderer(&renderer); backendImage1->setRenderer(&renderer); backendImage2->setRenderer(&renderer); + simulateInitializationSync(texture1, backendTexture1); + simulateInitializationSync(texture2, backendTexture2); + simulateInitializationSync(texture3, backendTexture3); + simulateInitializationSync(image1, backendImage1); + simulateInitializationSync(image2, backendImage2); // THEN QCOMPARE(backendTexture1->textureImageIds().size(), 1); @@ -765,9 +768,8 @@ private Q_SLOTS: // WHEN // Make Image1 dirty - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("dataGenerator"); - backendImage1->sceneChangeEvent(change); + image1->updateGenerator(); + backendImage1->syncFromFrontEnd(image1, false); // THEN QVERIFY(backendImage1->isDirty()); @@ -788,7 +790,8 @@ private Q_SLOTS: backendTexture3->unsetDirty(); // WHEN - backendImage2->sceneChangeEvent(change); + image2->updateGenerator(); + backendImage2->syncFromFrontEnd(image2, false); // THEN QVERIFY(backendImage2->isDirty()); -- cgit v1.2.3 From c718f6c7c9354f897c210ba74a8d8887762648f3 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 13:33:08 +0200 Subject: Update QShaderImage to use direct sync Change-Id: I582acdc7ce7d3e9d9967d4c053c47fe1728f5a44 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/materialsystem/shaderimage.cpp | 72 ++++++++++++----------- src/render/materialsystem/shaderimage_p.h | 4 +- tests/auto/render/shaderimage/tst_shaderimage.cpp | 56 ++++++++---------- 4 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index de27eb84f..03d3038fe 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -292,7 +292,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); - q->registerBackendType(QSharedPointer>::create(m_renderer)); + q->registerBackendType(QSharedPointer>::create(m_renderer)); // Framegraph q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/src/render/materialsystem/shaderimage.cpp b/src/render/materialsystem/shaderimage.cpp index cbda98ed0..c1fb72bfd 100644 --- a/src/render/materialsystem/shaderimage.cpp +++ b/src/render/materialsystem/shaderimage.cpp @@ -40,6 +40,7 @@ #include "shaderimage_p.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -70,44 +71,45 @@ void ShaderImage::cleanup() m_format = QShaderImage::NoFormat; } -void ShaderImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +void ShaderImage::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (e->type() == Qt3DCore::PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("texture")) { - m_textureId = propertyChange->value().value(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("mipLevel")) { - m_mipLevel = propertyChange->value().toInt(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("layer")) { - m_layer = propertyChange->value().toInt(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("layered")) { - m_layered = propertyChange->value().toBool(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("format")) { - m_format = propertyChange->value().value(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("access")) { - m_access = propertyChange->value().value(); - markDirty(AbstractRenderer::ParameterDirty); - } + const QShaderImage *node = qobject_cast(frontEnd); + if (!node) + return; + + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + const Qt3DCore::QNodeId textureNodeId = Qt3DCore::qIdForNode(node->texture()); + if (textureNodeId != m_textureId) { + m_textureId = textureNodeId; + markDirty(AbstractRenderer::ParameterDirty); + } + + if (node->mipLevel() != m_mipLevel) { + m_mipLevel = node->mipLevel(); + markDirty(AbstractRenderer::ParameterDirty); + } + + if (node->layer() != m_layer) { + m_layer = node->layer(); + markDirty(AbstractRenderer::ParameterDirty); + } + + if (node->layered() != m_layered) { + m_layered = node->layered(); + markDirty(AbstractRenderer::ParameterDirty); + } + + if (node->format() != m_format) { + m_format = node->format(); + markDirty(AbstractRenderer::ParameterDirty); + } + + if (node->access() != m_access) { + m_access = node->access(); + markDirty(AbstractRenderer::ParameterDirty); } - BackendNode::sceneChangeEvent(e); -} -void ShaderImage::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) -{ - const auto typedChange = qSharedPointerCast>(change); - const QShaderImageData &data = typedChange->data; - - m_textureId = data.textureId; - m_mipLevel = data.mipLevel; - m_layer = data.layer; - m_layered = data.layered; - m_access = data.access; - m_format = data.format; } } // namespace Render diff --git a/src/render/materialsystem/shaderimage_p.h b/src/render/materialsystem/shaderimage_p.h index 6e4de4186..1a1294a21 100644 --- a/src/render/materialsystem/shaderimage_p.h +++ b/src/render/materialsystem/shaderimage_p.h @@ -66,7 +66,7 @@ public: ShaderImage(); void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; Qt3DCore::QNodeId textureId() const { return m_textureId; } int mipLevel() const { return m_mipLevel; } @@ -86,8 +86,6 @@ public: #endif private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - Qt3DCore::QNodeId m_textureId; int m_mipLevel; int m_layer; diff --git a/tests/auto/render/shaderimage/tst_shaderimage.cpp b/tests/auto/render/shaderimage/tst_shaderimage.cpp index 6f1e691cc..6b2fc8ad7 100644 --- a/tests/auto/render/shaderimage/tst_shaderimage.cpp +++ b/tests/auto/render/shaderimage/tst_shaderimage.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include "qbackendnodetester.h" #include "testrenderer.h" @@ -98,11 +99,13 @@ private Q_SLOTS: { // GIVEN Qt3DRender::QShaderImage shaderImage; + TestRenderer renderer; { // WHEN Qt3DRender::Render::ShaderImage backendShaderImage; - simulateInitialization(&shaderImage, &backendShaderImage); + backendShaderImage.setRenderer(&renderer); + simulateInitializationSync(&shaderImage, &backendShaderImage); // THEN QCOMPARE(backendShaderImage.isEnabled(), true); @@ -118,7 +121,8 @@ private Q_SLOTS: // WHEN Qt3DRender::Render::ShaderImage backendShaderImage; shaderImage.setEnabled(false); - simulateInitialization(&shaderImage, &backendShaderImage); + backendShaderImage.setRenderer(&renderer); + simulateInitializationSync(&shaderImage, &backendShaderImage); // THEN QCOMPARE(backendShaderImage.peerId(), shaderImage.id()); @@ -129,39 +133,35 @@ private Q_SLOTS: void checkSceneChangeEvents() { // GIVEN + Qt3DRender::QShaderImage shaderImage; Qt3DRender::Render::ShaderImage backendShaderImage; TestRenderer renderer; backendShaderImage.setRenderer(&renderer); + simulateInitializationSync(&shaderImage, &backendShaderImage); { // WHEN const bool newValue = false; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("enabled"); - change->setValue(newValue); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setEnabled(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.isEnabled(), newValue); } { // WHEN - const Qt3DCore::QNodeId newValue = Qt3DCore::QNodeId::createId(); - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("texture"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + Qt3DRender::QTexture2D tex2D; + shaderImage.setTexture(&tex2D); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN - QCOMPARE(backendShaderImage.textureId(), newValue); + QCOMPARE(backendShaderImage.textureId(), tex2D.id()); } { // WHEN const int newValue = 883; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("mipLevel"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setMipLevel(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.mipLevel(), newValue); @@ -169,10 +169,8 @@ private Q_SLOTS: { // WHEN const int newValue = 1584; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("layer"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setLayer(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.layer(), newValue); @@ -180,10 +178,8 @@ private Q_SLOTS: { // WHEN const bool newValue = true; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("layered"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setLayered(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.layered(), newValue); @@ -191,10 +187,8 @@ private Q_SLOTS: { // WHEN const Qt3DRender::QShaderImage::Access newValue = Qt3DRender::QShaderImage::WriteOnly; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("access"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setAccess(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.access(), newValue); @@ -202,10 +196,8 @@ private Q_SLOTS: { // WHEN const Qt3DRender::QShaderImage::ImageFormat newValue = Qt3DRender::QShaderImage::RG16F; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("format"); - change->setValue(QVariant::fromValue(newValue)); - backendShaderImage.sceneChangeEvent(change); + shaderImage.setFormat(newValue); + backendShaderImage.syncFromFrontEnd(&shaderImage, false); // THEN QCOMPARE(backendShaderImage.format(), newValue); -- cgit v1.2.3 From 29dc5ced83b9d992ca533711d25ab31ebe984ee4 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 10:23:48 +0200 Subject: Update QFilterKey to use direct sync Change-Id: Ibeaa98c6aeb3180a233fba0d65e62c3076802833 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/materialsystem/filterkey.cpp | 28 ++++++----------- src/render/materialsystem/filterkey_p.h | 4 +-- tests/auto/render/filterkey/tst_filterkey.cpp | 44 +++++++++++++++------------ tests/auto/render/technique/tst_technique.cpp | 17 ++++++++--- 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 03d3038fe..ec8664e2b 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -282,7 +282,7 @@ void QRenderAspectPrivate::registerBackendTypes() // Material system q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/src/render/materialsystem/filterkey.cpp b/src/render/materialsystem/filterkey.cpp index 167413451..d51a06eec 100644 --- a/src/render/materialsystem/filterkey.cpp +++ b/src/render/materialsystem/filterkey.cpp @@ -65,31 +65,23 @@ void FilterKey::cleanup() m_value.clear(); } -void FilterKey::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void FilterKey::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_name = data.name; - m_value = data.value; -} + const QFilterKey *node = qobject_cast(frontEnd); + if (!node) + return; -void FilterKey::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case PropertyUpdated: { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - if (propertyChange->propertyName() == QByteArrayLiteral("value")) - m_value = propertyChange->value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("name")) - m_name = propertyChange->value().toString(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + if (node->name() != m_name) { + m_name = node->name(); markDirty(AbstractRenderer::AllDirty); } - default: - break; + if (node->value() != m_value) { + m_value = node->value(); + markDirty(AbstractRenderer::AllDirty); } - BackendNode::sceneChangeEvent(e); } bool FilterKey::operator ==(const FilterKey &other) diff --git a/src/render/materialsystem/filterkey_p.h b/src/render/materialsystem/filterkey_p.h index 69d298503..f4fb2c3d0 100644 --- a/src/render/materialsystem/filterkey_p.h +++ b/src/render/materialsystem/filterkey_p.h @@ -71,13 +71,11 @@ public: const QVariant &value() const { return m_value; } const QString &name() const { return m_name; } - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; bool operator ==(const FilterKey &other); bool operator !=(const FilterKey &other); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - QVariant m_value; QString m_name; }; diff --git a/tests/auto/render/filterkey/tst_filterkey.cpp b/tests/auto/render/filterkey/tst_filterkey.cpp index 15d07d65f..c998cc603 100644 --- a/tests/auto/render/filterkey/tst_filterkey.cpp +++ b/tests/auto/render/filterkey/tst_filterkey.cpp @@ -56,16 +56,18 @@ private Q_SLOTS: void checkCleanupState() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::FilterKey backendFilterKey; // WHEN + backendFilterKey.setRenderer(&renderer); backendFilterKey.setEnabled(true); { Qt3DRender::QFilterKey filterKey; filterKey.setName(QStringLiteral("Tim")); filterKey.setValue(QVariant(QStringLiteral("McGraw"))); - simulateInitialization(&filterKey, &backendFilterKey); + simulateInitializationSync(&filterKey, &backendFilterKey); } backendFilterKey.cleanup(); @@ -79,6 +81,7 @@ private Q_SLOTS: void checkInitializeFromPeer() { // GIVEN + TestRenderer renderer; Qt3DRender::QFilterKey filterKey; filterKey.setName(QStringLiteral("Dallas")); filterKey.setValue(QVariant(QStringLiteral("Smith"))); @@ -86,7 +89,8 @@ private Q_SLOTS: { // WHEN Qt3DRender::Render::FilterKey backendFilterKey; - simulateInitialization(&filterKey, &backendFilterKey); + backendFilterKey.setRenderer(&renderer); + simulateInitializationSync(&filterKey, &backendFilterKey); // THEN QCOMPARE(backendFilterKey.isEnabled(), true); @@ -97,8 +101,9 @@ private Q_SLOTS: { // WHEN Qt3DRender::Render::FilterKey backendFilterKey; + backendFilterKey.setRenderer(&renderer); filterKey.setEnabled(false); - simulateInitialization(&filterKey, &backendFilterKey); + simulateInitializationSync(&filterKey, &backendFilterKey); // THEN QCOMPARE(backendFilterKey.peerId(), filterKey.id()); @@ -110,16 +115,16 @@ private Q_SLOTS: { // GIVEN Qt3DRender::Render::FilterKey backendFilterKey; + Qt3DRender::QFilterKey frontend; TestRenderer renderer; backendFilterKey.setRenderer(&renderer); + simulateInitializationSync(&frontend, &backendFilterKey); { // WHEN const bool newValue = false; - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("enabled"); - change->setValue(newValue); - backendFilterKey.sceneChangeEvent(change); + frontend.setEnabled(newValue); + backendFilterKey.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backendFilterKey.isEnabled(), newValue); @@ -127,10 +132,8 @@ private Q_SLOTS: { // WHEN const QVariant newValue(383.0f); - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("value"); - change->setValue(QVariant::fromValue(newValue)); - backendFilterKey.sceneChangeEvent(change); + frontend.setValue(newValue); + backendFilterKey.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backendFilterKey.value(), newValue); @@ -138,10 +141,8 @@ private Q_SLOTS: { // WHEN const QString newValue = QStringLiteral("Alan"); - const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - change->setPropertyName("name"); - change->setValue(QVariant::fromValue(newValue)); - backendFilterKey.sceneChangeEvent(change); + frontend.setName(newValue); + backendFilterKey.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backendFilterKey.name(), newValue); @@ -151,10 +152,15 @@ private Q_SLOTS: void checkComparison() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::FilterKey backendFilterKey1; Qt3DRender::Render::FilterKey backendFilterKey2; Qt3DRender::Render::FilterKey backendFilterKey3; Qt3DRender::Render::FilterKey backendFilterKey4; + backendFilterKey1.setRenderer(&renderer); + backendFilterKey2.setRenderer(&renderer); + backendFilterKey3.setRenderer(&renderer); + backendFilterKey4.setRenderer(&renderer); // WHEN { @@ -162,20 +168,20 @@ private Q_SLOTS: filterKey1.setName(QStringLiteral("Dallas")); filterKey1.setValue(QVariant(QStringLiteral("Smith"))); - simulateInitialization(&filterKey1, &backendFilterKey1); - simulateInitialization(&filterKey1, &backendFilterKey4); + simulateInitializationSync(&filterKey1, &backendFilterKey1); + simulateInitializationSync(&filterKey1, &backendFilterKey4); Qt3DRender::QFilterKey filterKey2; filterKey2.setName(QStringLiteral("Tim")); filterKey2.setValue(QVariant(QStringLiteral("Smith"))); - simulateInitialization(&filterKey2, &backendFilterKey2); + simulateInitializationSync(&filterKey2, &backendFilterKey2); Qt3DRender::QFilterKey filterKey3; filterKey3.setName(QStringLiteral("Dallas")); filterKey3.setValue(QVariant(QStringLiteral("McGraw"))); - simulateInitialization(&filterKey3, &backendFilterKey3); + simulateInitializationSync(&filterKey3, &backendFilterKey3); } // THEN diff --git a/tests/auto/render/technique/tst_technique.cpp b/tests/auto/render/technique/tst_technique.cpp index 64a66f0c8..2ed39e315 100644 --- a/tests/auto/render/technique/tst_technique.cpp +++ b/tests/auto/render/technique/tst_technique.cpp @@ -308,6 +308,7 @@ private Q_SLOTS: void checkIsCompatibleWithFilters() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::Technique backendTechnique; Qt3DRender::Render::NodeManagers nodeManagers; @@ -339,11 +340,17 @@ private Q_SLOTS: Qt3DRender::Render::FilterKey *backendFilterKey4 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey4->id()); Qt3DRender::Render::FilterKey *backendFilterKey5 = nodeManagers.filterKeyManager()->getOrCreateResource(filterKey5->id()); - simulateInitialization(filterKey1, backendFilterKey1); - simulateInitialization(filterKey2, backendFilterKey2); - simulateInitialization(filterKey3, backendFilterKey3); - simulateInitialization(filterKey4, backendFilterKey4); - simulateInitialization(filterKey5, backendFilterKey5); + backendFilterKey1->setRenderer(&renderer); + backendFilterKey2->setRenderer(&renderer); + backendFilterKey3->setRenderer(&renderer); + backendFilterKey4->setRenderer(&renderer); + backendFilterKey5->setRenderer(&renderer); + + simulateInitializationSync(filterKey1, backendFilterKey1); + simulateInitializationSync(filterKey2, backendFilterKey2); + simulateInitializationSync(filterKey3, backendFilterKey3); + simulateInitializationSync(filterKey4, backendFilterKey4); + simulateInitializationSync(filterKey5, backendFilterKey5); // THEN QCOMPARE(nodeManagers.filterKeyManager()->activeHandles().size(), 5); -- cgit v1.2.3 From b8435ca421d5612afabec1d717ea0a29be8a9c5c Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 15:58:20 +0200 Subject: Update QShaderProgram to use direct sync Change-Id: I71cac1345ed7b9e14b8cdc479c60f0384bb0b198 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/materialsystem/shader.cpp | 56 ++++++++++----------------------- src/render/materialsystem/shader_p.h | 4 +-- tests/auto/render/shader/tst_shader.cpp | 52 ++++++++++++------------------ 4 files changed, 39 insertions(+), 75 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index ec8664e2b..804dbef6c 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -289,7 +289,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer>::create(m_renderer)); diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index d42b0dda7..f35fba9fa 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -101,23 +101,24 @@ void Shader::cleanup() m_status = QShaderProgram::NotReady; } -void Shader::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void Shader::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - - for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) - m_shaderCode[i].clear(); - - m_shaderCode[QShaderProgram::Vertex] = data.vertexShaderCode; - m_shaderCode[QShaderProgram::TessellationControl] = data.tessellationControlShaderCode; - m_shaderCode[QShaderProgram::TessellationEvaluation] = data.tessellationEvaluationShaderCode; - m_shaderCode[QShaderProgram::Geometry] = data.geometryShaderCode; - m_shaderCode[QShaderProgram::Fragment] = data.fragmentShaderCode; - m_shaderCode[QShaderProgram::Compute] = data.computeShaderCode; - m_isLoaded = false; - updateDNA(); - markDirty(AbstractRenderer::ShadersDirty); + const QShaderProgram *node = qobject_cast(frontEnd); + if (!node) + return; + + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (firstTime) + for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) + m_shaderCode[i].clear(); + + for (int i = QShaderProgram::Vertex; i <= QShaderProgram::Compute; ++i) { + const QShaderProgram::ShaderType shaderType = static_cast(i); + const QByteArray code = node->shaderCode(shaderType); + if (code != m_shaderCode.value(shaderType)) + setShaderCode(shaderType, code); + } } void Shader::setGraphicsContext(GraphicsContext *context) @@ -174,29 +175,6 @@ void Shader::setShaderCode(QShaderProgram::ShaderType type, const QByteArray &co markDirty(AbstractRenderer::ShadersDirty); } -void Shader::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = e.staticCast(); - QVariant propertyValue = propertyChange->value(); - - if (propertyChange->propertyName() == QByteArrayLiteral("vertexShaderCode")) - setShaderCode(QShaderProgram::Vertex, propertyValue.toByteArray()); - else if (propertyChange->propertyName() == QByteArrayLiteral("fragmentShaderCode")) - setShaderCode(QShaderProgram::Fragment, propertyValue.toByteArray()); - else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationControlShaderCode")) - setShaderCode(QShaderProgram::TessellationControl, propertyValue.toByteArray()); - else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationEvaluationShaderCode")) - setShaderCode(QShaderProgram::TessellationEvaluation, propertyValue.toByteArray()); - else if (propertyChange->propertyName() == QByteArrayLiteral("geometryShaderCode")) - setShaderCode(QShaderProgram::Geometry, propertyValue.toByteArray()); - else if (propertyChange->propertyName() == QByteArrayLiteral("computeShaderCode")) - setShaderCode(QShaderProgram::Compute, propertyValue.toByteArray()); - } - - BackendNode::sceneChangeEvent(e); -} - QHash Shader::activeUniformsForUniformBlock(int blockIndex) const { return m_uniformBlockIndexToShaderUniforms.value(blockIndex); diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index 9eb24904c..f8cdde3b7 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -99,7 +99,7 @@ public: QVector shaderCode() const; void setShaderCode(QShaderProgram::ShaderType type, const QByteArray &code); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; bool isLoaded() const { QMutexLocker lock(&m_mutex); return m_isLoaded; } void setLoaded(bool loaded) { QMutexLocker lock(&m_mutex); m_isLoaded = loaded; } ProgramDNA dna() const Q_DECL_NOTHROW { return m_dna; } @@ -126,8 +126,6 @@ public: inline bool hasPendingNotifications() const { return !m_pendingNotifications.empty(); } private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - QVector m_uniformsNames; QVector m_uniformsNamesIds; QVector m_uniforms; diff --git a/tests/auto/render/shader/tst_shader.cpp b/tests/auto/render/shader/tst_shader.cpp index 067db55e7..bfebe2467 100644 --- a/tests/auto/render/shader/tst_shader.cpp +++ b/tests/auto/render/shader/tst_shader.cpp @@ -97,7 +97,7 @@ void tst_RenderShader::matchesFrontendPeer() Qt3DRender::Render::Shader backend; backend.setRenderer(&renderer); - simulateInitialization(frontend.data(), &backend); + simulateInitializationSync(frontend.data(), &backend); QCOMPARE(backend.isLoaded(), false); QVERIFY(backend.dna() != 0U); @@ -113,7 +113,7 @@ void tst_RenderShader::cleanupLeavesACoherentState() Qt3DRender::Render::Shader shader; shader.setRenderer(&renderer); - simulateInitialization(frontend.data(), &shader); + simulateInitializationSync(frontend.data(), &shader); shader.cleanup(); @@ -130,73 +130,61 @@ void tst_RenderShader::cleanupLeavesACoherentState() void tst_RenderShader::dealWithPropertyChanges_data() { - QTest::addColumn("property"); QTest::addColumn("type"); - QTest::newRow("vertex") << QByteArrayLiteral("vertexShaderCode") - << Qt3DRender::QShaderProgram::Vertex; + QTest::newRow("vertex") << Qt3DRender::QShaderProgram::Vertex; - QTest::newRow("tessControl") << QByteArrayLiteral("tessellationControlShaderCode") - << Qt3DRender::QShaderProgram::TessellationControl; + QTest::newRow("tessControl") << Qt3DRender::QShaderProgram::TessellationControl; - QTest::newRow("tessEval") << QByteArrayLiteral("tessellationEvaluationShaderCode") - << Qt3DRender::QShaderProgram::TessellationEvaluation; + QTest::newRow("tessEval") << Qt3DRender::QShaderProgram::TessellationEvaluation; - QTest::newRow("geometry") << QByteArrayLiteral("geometryShaderCode") - << Qt3DRender::QShaderProgram::Geometry; + QTest::newRow("geometry") << Qt3DRender::QShaderProgram::Geometry; - QTest::newRow("fragment") << QByteArrayLiteral("fragmentShaderCode") - << Qt3DRender::QShaderProgram::Fragment; + QTest::newRow("fragment") << Qt3DRender::QShaderProgram::Fragment; - QTest::newRow("compute") << QByteArrayLiteral("computeShaderCode") - << Qt3DRender::QShaderProgram::Compute; + QTest::newRow("compute") << Qt3DRender::QShaderProgram::Compute; } void tst_RenderShader::dealWithPropertyChanges() { // GIVEN - QFETCH(QByteArray, property); QFETCH(Qt3DRender::QShaderProgram::ShaderType, type); Qt3DRender::Render::Shader backend; + Qt3DRender::QShaderProgram shader; backend.setLoaded(true); TestRenderer renderer; backend.setRenderer(&renderer); + simulateInitializationSync(&shader, &backend); // WHEN - auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QStringLiteral("foo")); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + shader.setShaderCode(type, QByteArrayLiteral("foo")); + backend.syncFromFrontEnd(&shader, false); // THEN - QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo")); + QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("foo")); QVERIFY(!backend.isLoaded()); QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); renderer.resetDirty(); backend.setLoaded(true); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QStringLiteral("foo")); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + shader.setShaderCode(type, QByteArrayLiteral("foo")); + backend.syncFromFrontEnd(&shader, false); // THEN - QCOMPARE(backend.shaderCode().at(type), QStringLiteral("foo")); + QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("foo")); QVERIFY(backend.isLoaded()); QCOMPARE(renderer.dirtyBits(), 0); renderer.resetDirty(); backend.setLoaded(true); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QStringLiteral("bar")); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + shader.setShaderCode(type, QByteArrayLiteral("bar")); + backend.syncFromFrontEnd(&shader, false); // THEN - QCOMPARE(backend.shaderCode().at(type), QStringLiteral("bar")); + QCOMPARE(backend.shaderCode().at(type), QByteArrayLiteral("bar")); QVERIFY(!backend.isLoaded()); QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); renderer.resetDirty(); @@ -216,7 +204,7 @@ void tst_RenderShader::checkSetRendererDirtyOnInitialization() QCOMPARE(renderer.dirtyBits(), 0); // WHEN - simulateInitialization(frontend.data(), &shader); + simulateInitializationSync(frontend.data(), &shader); // THEN QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); -- cgit v1.2.3 From 637a9d688a85c452ac0a20378961081a08980cf6 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Thu, 19 Sep 2019 17:00:01 +0200 Subject: Update QShaderProgramBuilder to use direct sync Change-Id: Ia96175b95ad8e852e1c65deb34070e0ef7e30bd2 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/materialsystem/shaderbuilder.cpp | 71 +++++---- src/render/materialsystem/shaderbuilder_p.h | 3 +- .../render/shaderbuilder/tst_shaderbuilder.cpp | 162 ++++++++++----------- 4 files changed, 114 insertions(+), 124 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 804dbef6c..cea97be69 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -290,7 +290,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer::create(m_renderer, m_nodeManagers)); q->registerBackendType(QSharedPointer>::create(m_renderer)); diff --git a/src/render/materialsystem/shaderbuilder.cpp b/src/render/materialsystem/shaderbuilder.cpp index c1ec7f75a..b80a66a50 100644 --- a/src/render/materialsystem/shaderbuilder.cpp +++ b/src/render/materialsystem/shaderbuilder.cpp @@ -279,47 +279,46 @@ void ShaderBuilder::generateCode(ShaderBuilder::ShaderType type) notifyObservers(propertyChange); } -void ShaderBuilder::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +void ShaderBuilder::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) { - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = e.staticCast(); - QVariant propertyValue = propertyChange->value(); - - if (propertyChange->propertyName() == QByteArrayLiteral("shaderProgram")) - m_shaderProgramId = propertyValue.value(); - else if (propertyChange->propertyName() == QByteArrayLiteral("enabledLayers")) - setEnabledLayers(propertyValue.toStringList()); - else if (propertyChange->propertyName() == QByteArrayLiteral("vertexShaderGraph")) - setShaderGraph(Vertex, propertyValue.toUrl()); - else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationControlShaderGraph")) - setShaderGraph(TessellationControl, propertyValue.toUrl()); - else if (propertyChange->propertyName() == QByteArrayLiteral("tessellationEvaluationShaderGraph")) - setShaderGraph(TessellationEvaluation, propertyValue.toUrl()); - else if (propertyChange->propertyName() == QByteArrayLiteral("geometryShaderGraph")) - setShaderGraph(Geometry, propertyValue.toUrl()); - else if (propertyChange->propertyName() == QByteArrayLiteral("fragmentShaderGraph")) - setShaderGraph(Fragment, propertyValue.toUrl()); - else if (propertyChange->propertyName() == QByteArrayLiteral("computeShaderGraph")) - setShaderGraph(Compute, propertyValue.toUrl()); + const QShaderProgramBuilder *node = qobject_cast(frontEnd); + if (!node) + return; + + const bool oldEnabled = isEnabled(); + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + if (oldEnabled != isEnabled()) { markDirty(AbstractRenderer::ShadersDirty); } - BackendNode::sceneChangeEvent(e); -} -void ShaderBuilder::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) -{ - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - - m_shaderProgramId = data.shaderProgramId; - m_enabledLayers = data.enabledLayers; - setShaderGraph(Vertex, data.vertexShaderGraph); - setShaderGraph(TessellationControl, data.tessellationControlShaderGraph); - setShaderGraph(TessellationEvaluation, data.tessellationEvaluationShaderGraph); - setShaderGraph(Geometry, data.geometryShaderGraph); - setShaderGraph(Fragment, data.fragmentShaderGraph); - setShaderGraph(Compute, data.computeShaderGraph); + const Qt3DCore::QNodeId shaderProgramId = Qt3DCore::qIdForNode(node->shaderProgram()); + if (shaderProgramId != m_shaderProgramId) { + m_shaderProgramId = shaderProgramId; + markDirty(AbstractRenderer::ShadersDirty); + } + + if (node->enabledLayers() != m_enabledLayers) { + setEnabledLayers(node->enabledLayers()); + markDirty(AbstractRenderer::ShadersDirty); + } + + static const std::pair shaderTypesToGetters[] = { + {Vertex, &QShaderProgramBuilder::vertexShaderGraph}, + {TessellationControl, &QShaderProgramBuilder::tessellationControlShaderGraph}, + {TessellationEvaluation, &QShaderProgramBuilder::tessellationEvaluationShaderGraph}, + {Geometry, &QShaderProgramBuilder::geometryShaderGraph}, + {Fragment, &QShaderProgramBuilder::fragmentShaderGraph}, + {Compute, &QShaderProgramBuilder::computeShaderGraph}, + }; + + for (auto it = std::cbegin(shaderTypesToGetters), end = std::cend(shaderTypesToGetters); it != end; ++it) { + const QUrl url = (node->*(it->second))(); + if (url != m_graphs.value(it->first)) { + setShaderGraph(it->first, url); + markDirty(AbstractRenderer::ShadersDirty); + } + } } } // namespace Render diff --git a/src/render/materialsystem/shaderbuilder_p.h b/src/render/materialsystem/shaderbuilder_p.h index 00c4e1c28..12234bb6c 100644 --- a/src/render/materialsystem/shaderbuilder_p.h +++ b/src/render/materialsystem/shaderbuilder_p.h @@ -95,10 +95,9 @@ public: void generateCode(ShaderType type); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; void setEnabledLayers(const QStringList &layers); GraphicsApiFilterData m_graphicsApi; diff --git a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp index e365256cc..c9a290dbd 100644 --- a/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp +++ b/tests/auto/render/shaderbuilder/tst_shaderbuilder.cpp @@ -141,9 +141,11 @@ private slots: // GIVEN QFETCH(Qt3DRender::QShaderProgramBuilder*, frontend); Qt3DRender::Render::ShaderBuilder backend; + TestRenderer renderer; // WHEN - simulateInitialization(frontend, &backend); + backend.setRenderer(&renderer); + simulateInitializationSync(frontend, &backend); // THEN QVERIFY(backend.isEnabled() == frontend->isEnabled()); @@ -199,25 +201,14 @@ private slots: { // GIVEN Qt3DRender::Render::ShaderBuilder backend; + Qt3DRender::QShaderProgramBuilder frontend; TestRenderer renderer; backend.setRenderer(&renderer); + simulateInitializationSync(&frontend, &backend); // WHEN - auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(true); - updateChange->setPropertyName("enabled"); - backend.sceneChangeEvent(updateChange); - - // THEN - QVERIFY(backend.isEnabled()); - QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); - renderer.resetDirty(); - - // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(false); - updateChange->setPropertyName("enabled"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabled(false); + backend.syncFromFrontEnd(&frontend, false); // THEN QVERIFY(!backend.isEnabled()); @@ -225,10 +216,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(true); - updateChange->setPropertyName("enabled"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabled(true); + backend.syncFromFrontEnd(&frontend, false); // AND backend.cleanup(); @@ -242,26 +231,24 @@ private slots: { // GIVEN Qt3DRender::Render::ShaderBuilder backend; + Qt3DRender::QShaderProgramBuilder frontend; TestRenderer renderer; backend.setRenderer(&renderer); - const auto programId = Qt3DCore::QNodeId::createId(); + simulateInitializationSync(&frontend, &backend); // WHEN - auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QVariant::fromValue(programId)); - updateChange->setPropertyName("shaderProgram"); - backend.sceneChangeEvent(updateChange); + Qt3DRender::QShaderProgram prog; + frontend.setShaderProgram(&prog); + backend.syncFromFrontEnd(&frontend, false); // THEN - QCOMPARE(backend.shaderProgramId(), programId); + QCOMPARE(backend.shaderProgramId(), prog.id()); QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QVariant::fromValue(Qt3DCore::QNodeId())); - updateChange->setPropertyName("shaderProgram"); - backend.sceneChangeEvent(updateChange); + frontend.setShaderProgram(nullptr); + backend.syncFromFrontEnd(&frontend, false); // THEN QVERIFY(backend.shaderProgramId().isNull()); @@ -269,10 +256,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QVariant::fromValue(programId)); - updateChange->setPropertyName("shaderProgram"); - backend.sceneChangeEvent(updateChange); + frontend.setShaderProgram(&prog); + backend.syncFromFrontEnd(&frontend, false); // AND backend.cleanup(); @@ -286,21 +271,34 @@ private slots: { // GIVEN Qt3DRender::Render::ShaderBuilder backend; + Qt3DRender::QShaderProgramBuilder frontend; TestRenderer renderer; backend.setRenderer(&renderer); + simulateInitializationSync(&frontend, &backend); const auto layers = QStringList() << "foo" << "bar"; - for (int i = 0; i <= Qt3DRender::Render::ShaderBuilder::Compute; i++) { - const auto type = static_cast(i); + static const std::pair< + Qt3DRender::Render::ShaderBuilder::ShaderType, + void (Qt3DRender::QShaderProgramBuilder::*)(const QUrl &) + > + shaderTypesToSetters[] = { + {Qt3DRender::Render::ShaderBuilder::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, + }; + + + for (auto it = std::begin(shaderTypesToSetters), end = std::end(shaderTypesToSetters); it != end; ++it) { const auto graphUrl = QUrl::fromEncoded("qrc:/input.json"); - backend.setShaderGraph(type, graphUrl); + (frontend.*(it->second))(graphUrl); } // WHEN - auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(layers); - updateChange->setPropertyName("enabledLayers"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabledLayers(layers); + backend.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backend.enabledLayers(), layers); @@ -313,10 +311,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(layers); - updateChange->setPropertyName("enabledLayers"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabledLayers(layers); + backend.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backend.enabledLayers(), layers); @@ -325,14 +321,12 @@ private slots: QVERIFY(!backend.isShaderCodeDirty(type)); backend.generateCode(type); // Resets the dirty flag } - QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); + QCOMPARE(renderer.dirtyBits(), 0); renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QStringList()); - updateChange->setPropertyName("enabledLayers"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabledLayers(QStringList()); + backend.syncFromFrontEnd(&frontend, false); // THEN QVERIFY(backend.shaderProgramId().isNull()); @@ -345,10 +339,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(layers); - updateChange->setPropertyName("enabledLayers"); - backend.sceneChangeEvent(updateChange); + frontend.setEnabledLayers(layers); + backend.syncFromFrontEnd(&frontend, false); // AND backend.cleanup(); @@ -365,64 +357,68 @@ private slots: void shouldHandleShaderGraphPropertiesChanges_data() { - QTest::addColumn("property"); QTest::addColumn("type"); QTest::addColumn("graphUrl"); - QTest::newRow("vertex") << QByteArrayLiteral("vertexShaderGraph") - << Qt3DRender::Render::ShaderBuilder::Vertex + QTest::newRow("vertex") << Qt3DRender::Render::ShaderBuilder::Vertex << QUrl::fromEncoded("qrc:/vertex.json"); - QTest::newRow("tessControl") << QByteArrayLiteral("tessellationControlShaderGraph") - << Qt3DRender::Render::ShaderBuilder::TessellationControl + QTest::newRow("tessControl") << Qt3DRender::Render::ShaderBuilder::TessellationControl << QUrl::fromEncoded("qrc:/tesscontrol.json"); - QTest::newRow("tessEval") << QByteArrayLiteral("tessellationEvaluationShaderGraph") - << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation + QTest::newRow("tessEval") << Qt3DRender::Render::ShaderBuilder::TessellationEvaluation << QUrl::fromEncoded("qrc:/tesseval.json"); - QTest::newRow("geometry") << QByteArrayLiteral("geometryShaderGraph") - << Qt3DRender::Render::ShaderBuilder::Geometry + QTest::newRow("geometry") << Qt3DRender::Render::ShaderBuilder::Geometry << QUrl::fromEncoded("qrc:/geometry.json"); - QTest::newRow("fragment") << QByteArrayLiteral("fragmentShaderGraph") - << Qt3DRender::Render::ShaderBuilder::Fragment + QTest::newRow("fragment") << Qt3DRender::Render::ShaderBuilder::Fragment << QUrl::fromEncoded("qrc:/fragment.json"); - QTest::newRow("compute") << QByteArrayLiteral("computeShaderGraph") - << Qt3DRender::Render::ShaderBuilder::Compute + QTest::newRow("compute") << Qt3DRender::Render::ShaderBuilder::Compute << QUrl::fromEncoded("qrc:/compute.json"); } void shouldHandleShaderGraphPropertiesChanges() { // GIVEN - QFETCH(QByteArray, property); QFETCH(Qt3DRender::Render::ShaderBuilder::ShaderType, type); QFETCH(QUrl, graphUrl); Qt3DRender::Render::ShaderBuilder backend; + Qt3DRender::QShaderProgramBuilder frontend; TestRenderer renderer; backend.setRenderer(&renderer); + simulateInitializationSync(&frontend, &backend); + + static const QHash< + Qt3DRender::Render::ShaderBuilder::ShaderType, + void (Qt3DRender::QShaderProgramBuilder::*)(const QUrl &) + > + shaderTypesToSetters = { + {Qt3DRender::Render::ShaderBuilder::Vertex, &Qt3DRender::QShaderProgramBuilder::setVertexShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::TessellationControl, &Qt3DRender::QShaderProgramBuilder::setTessellationControlShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::TessellationEvaluation, &Qt3DRender::QShaderProgramBuilder::setTessellationEvaluationShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Geometry, &Qt3DRender::QShaderProgramBuilder::setGeometryShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Fragment, &Qt3DRender::QShaderProgramBuilder::setFragmentShaderGraph}, + {Qt3DRender::Render::ShaderBuilder::Compute, &Qt3DRender::QShaderProgramBuilder::setComputeShaderGraph}, + }; // WHEN - auto updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QUrl()); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + + (frontend.*(shaderTypesToSetters[type]))(QUrl()); + backend.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backend.shaderGraph(type), QUrl()); QVERIFY(!backend.isShaderCodeDirty(type)); QVERIFY(backend.shaderCode(type).isEmpty()); - QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::ShadersDirty); + QCOMPARE(renderer.dirtyBits(), 0); renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(graphUrl); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + (frontend.*(shaderTypesToSetters[type]))(graphUrl); + backend.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backend.shaderGraph(type), graphUrl); @@ -432,10 +428,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(QUrl()); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + (frontend.*(shaderTypesToSetters[type]))(QUrl()); + backend.syncFromFrontEnd(&frontend, false); // THEN QCOMPARE(backend.shaderGraph(type), QUrl()); @@ -445,10 +439,8 @@ private slots: renderer.resetDirty(); // WHEN - updateChange = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId()); - updateChange->setValue(graphUrl); - updateChange->setPropertyName(property); - backend.sceneChangeEvent(updateChange); + (frontend.*(shaderTypesToSetters[type]))(graphUrl); + backend.syncFromFrontEnd(&frontend, false); // AND backend.cleanup(); -- cgit v1.2.3 From 17e17494720843772ec8132baea661d224f79adc Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 20 Sep 2019 07:45:25 +0200 Subject: Update QObjectPicker to use direct sync Change-Id: Ia11bdb1ebf26f5d2cc25bc66172302bbf3c4f149 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 2 +- src/render/picking/objectpicker.cpp | 48 +++++++++++----------- src/render/picking/objectpicker_p.h | 3 +- .../auto/render/objectpicker/tst_objectpicker.cpp | 33 ++++++++------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index cea97be69..2e5229364 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -320,7 +320,7 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType(QSharedPointer >::create(m_renderer)); // Picking - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); q->registerBackendType(QSharedPointer >::create(m_renderer)); diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp index 0b3846621..e278d6b6f 100644 --- a/src/render/picking/objectpicker.cpp +++ b/src/render/picking/objectpicker.cpp @@ -75,40 +75,38 @@ void ObjectPicker::cleanup() notifyJob(); } -void ObjectPicker::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void ObjectPicker::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_hoverEnabled = data.hoverEnabled; - m_dragEnabled = data.dragEnabled; - m_priority = data.priority; - notifyJob(); -} + const QObjectPicker *node = qobject_cast(frontEnd); + if (!node) + return; -void ObjectPicker::notifyJob() -{ - if (m_renderer && m_renderer->pickBoundingVolumeJob()) - qSharedPointerCast(m_renderer->pickBoundingVolumeJob())->markPickersDirty(); -} + BackendNode::syncFromFrontEnd(frontEnd, firstTime); -void ObjectPicker::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == Qt3DCore::PropertyUpdated) { - const Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); + if (node->isHoverEnabled() != m_hoverEnabled) { + m_hoverEnabled = node->isHoverEnabled(); + markDirty(AbstractRenderer::AllDirty); + notifyJob(); + } - if (propertyChange->propertyName() == QByteArrayLiteral("hoverEnabled")) { - m_hoverEnabled = propertyChange->value().toBool(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("dragEnabled")) { - m_dragEnabled = propertyChange->value().toBool(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("priority")) { - m_priority = propertyChange->value().toInt(); - } + if (node->isDragEnabled() != m_dragEnabled) { + m_dragEnabled = node->isDragEnabled(); + markDirty(AbstractRenderer::AllDirty); + notifyJob(); + } + if (node->priority() != m_priority) { + m_priority = node->priority(); markDirty(AbstractRenderer::AllDirty); notifyJob(); } - BackendNode::sceneChangeEvent(e); +} + +void ObjectPicker::notifyJob() +{ + if (m_renderer && m_renderer->pickBoundingVolumeJob()) + qSharedPointerCast(m_renderer->pickBoundingVolumeJob())->markPickersDirty(); } bool ObjectPicker::isPressed() const diff --git a/src/render/picking/objectpicker_p.h b/src/render/picking/objectpicker_p.h index 1e8bf12bf..b4f7d073c 100644 --- a/src/render/picking/objectpicker_p.h +++ b/src/render/picking/objectpicker_p.h @@ -69,7 +69,7 @@ public: ~ObjectPicker(); void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) final; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; bool isPressed() const; bool isHoverEnabled() const; bool isDragEnabled() const; @@ -86,7 +86,6 @@ public: int priority() const; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; void notifyJob(); int m_priority; diff --git a/tests/auto/render/objectpicker/tst_objectpicker.cpp b/tests/auto/render/objectpicker/tst_objectpicker.cpp index 99b2af538..a8d9bd010 100644 --- a/tests/auto/render/objectpicker/tst_objectpicker.cpp +++ b/tests/auto/render/objectpicker/tst_objectpicker.cpp @@ -44,13 +44,15 @@ private Q_SLOTS: void checkPeerPropertyMirroring() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::ObjectPicker objectPicker; Qt3DRender::QObjectPicker picker; picker.setHoverEnabled(true); picker.setPriority(883); // WHEN - simulateInitialization(&picker, &objectPicker); + objectPicker.setRenderer(&renderer); + simulateInitializationSync(&picker, &objectPicker); // THEN QVERIFY(!objectPicker.peerId().isNull()); @@ -61,6 +63,7 @@ private Q_SLOTS: void checkInitialAndCleanedUpState() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::ObjectPicker objectPicker; // THEN @@ -76,7 +79,8 @@ private Q_SLOTS: picker.setPriority(1584); // WHEN - simulateInitialization(&picker, &objectPicker); + objectPicker.setRenderer(&renderer); + simulateInitializationSync(&picker, &objectPicker); objectPicker.cleanup(); // THEN @@ -90,42 +94,43 @@ private Q_SLOTS: // GIVEN TestRenderer renderer; { + Qt3DRender::QObjectPicker picker; Qt3DRender::Render::ObjectPicker objectPicker; objectPicker.setRenderer(&renderer); + simulateInitializationSync(&picker, &objectPicker); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(true); - updateChange->setPropertyName("hoverEnabled"); - objectPicker.sceneChangeEvent(updateChange); + picker.setHoverEnabled(true); + objectPicker.syncFromFrontEnd(&picker, false); // THEN QCOMPARE(objectPicker.isHoverEnabled(), true); QVERIFY(renderer.dirtyBits() != 0); } { + Qt3DRender::QObjectPicker picker; Qt3DRender::Render::ObjectPicker objectPicker; objectPicker.setRenderer(&renderer); + simulateInitializationSync(&picker, &objectPicker); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(true); - updateChange->setPropertyName("dragEnabled"); - objectPicker.sceneChangeEvent(updateChange); + picker.setDragEnabled(true); + objectPicker.syncFromFrontEnd(&picker, false); + // THEN QCOMPARE(objectPicker.isDragEnabled(), true); QVERIFY(renderer.dirtyBits() != 0); } { + Qt3DRender::QObjectPicker picker; Qt3DRender::Render::ObjectPicker objectPicker; objectPicker.setRenderer(&renderer); + simulateInitializationSync(&picker, &objectPicker); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(15); - updateChange->setPropertyName("priority"); - objectPicker.sceneChangeEvent(updateChange); + picker.setPriority(15); + objectPicker.syncFromFrontEnd(&picker, false); // THEN QCOMPARE(objectPicker.priority(), 15); -- cgit v1.2.3 From cbfa01d796aa8e95bb5f8985169c1b1a83d08d6b Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 20 Sep 2019 08:13:09 +0200 Subject: Update QAbstractRayCaster to use direct sync Change-Id: Iad0b1e7f06081a3cc77bc0c18a751a0e08291699 Reviewed-by: Mike Krus --- src/render/frontend/qrenderaspect.cpp | 4 +- src/render/picking/raycaster.cpp | 96 +++++++++++++-------------- src/render/picking/raycaster_p.h | 3 +- tests/auto/render/raycaster/tst_raycaster.cpp | 16 +++-- 4 files changed, 58 insertions(+), 61 deletions(-) diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp index 2e5229364..70ec70b2b 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -321,8 +321,8 @@ void QRenderAspectPrivate::registerBackendTypes() // Picking q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); - q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); + q->registerBackendType(QSharedPointer >::create(m_renderer)); // Plugins for (const QString &plugin : qAsConst(m_pluginConfig)) diff --git a/src/render/picking/raycaster.cpp b/src/render/picking/raycaster.cpp index a5fbf1206..34bbaefd9 100644 --- a/src/render/picking/raycaster.cpp +++ b/src/render/picking/raycaster.cpp @@ -41,6 +41,7 @@ #include "qpickevent.h" #include #include +#include #include #include #include @@ -119,70 +120,63 @@ void RayCaster::cleanup() notifyJob(); } -void RayCaster::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) +void RayCaster::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_type = data.casterType; - m_runMode = data.runMode; - m_origin = data.origin; - m_direction = data.direction; - m_length = data.length; - m_position = data.position; - m_filterMode = data.filterMode; - m_layerIds = data.layerIds; -} + const QAbstractRayCaster *node = qobject_cast(frontEnd); + if (!node) + return; -void RayCaster::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case PropertyValueAdded: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("layer")) { - m_layerIds.append(change->addedNodeId()); - markDirty(AbstractRenderer::LayersDirty); - notifyJob(); - } - break; + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + + if (node->runMode() != m_runMode) { + m_runMode = node->runMode(); + notifyJob(); + markDirty(AbstractRenderer::AllDirty); + } + + if (node->filterMode() != m_filterMode) { + m_filterMode = node->filterMode(); + notifyJob(); + markDirty(AbstractRenderer::AllDirty); + } + + const Qt3DCore::QNodeIdVector layerIds = Qt3DCore::qIdsForNodes(node->layers()); + if (layerIds != m_layerIds) { + m_layerIds = layerIds; + markDirty(AbstractRenderer::LayersDirty); + notifyJob(); } - case PropertyValueRemoved: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("layer")) { - m_layerIds.removeOne(change->removedNodeId()); - markDirty(AbstractRenderer::LayersDirty); - notifyJob(); - } - break; + const QAbstractRayCasterPrivate *d = static_cast(QNodePrivate::get(node)); + if (d->m_direction != m_direction) { + m_direction = d->m_direction; + notifyJob(); + markDirty(AbstractRenderer::AllDirty); } - case PropertyUpdated: { - const Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(e); - - if (propertyChange->propertyName() == QByteArrayLiteral("origin")) { - m_origin = propertyChange->value().value(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("direction")) { - m_direction = propertyChange->value().value(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("length")) { - m_length = propertyChange->value().toFloat(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("position")) { - m_position = propertyChange->value().toPoint(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("runMode")) { - m_runMode = propertyChange->value().value(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("filterMode")) { - m_filterMode = propertyChange->value().value(); - } + if (!qFuzzyCompare(d->m_length, m_length)) { + m_length = d->m_length; + notifyJob(); + markDirty(AbstractRenderer::AllDirty); + } + if (d->m_origin != m_origin) { + m_origin = d->m_origin; notifyJob(); markDirty(AbstractRenderer::AllDirty); - break; } - default: - break; + if (d->m_position != m_position) { + m_position = d->m_position; + notifyJob(); + markDirty(AbstractRenderer::AllDirty); } - BackendNode::sceneChangeEvent(e); + if (d->m_rayCasterType != m_type) { + m_type = d->m_rayCasterType; + notifyJob(); + markDirty(AbstractRenderer::AllDirty); + } } void RayCaster::dispatchHits(const QAbstractRayCaster::Hits &hits) diff --git a/src/render/picking/raycaster_p.h b/src/render/picking/raycaster_p.h index 6fe6ee322..2be87ec3c 100644 --- a/src/render/picking/raycaster_p.h +++ b/src/render/picking/raycaster_p.h @@ -80,13 +80,12 @@ public: Qt3DCore::QNodeIdVector layerIds() const; QAbstractRayCaster::FilterMode filterMode() const; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; void cleanup(); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) final; void dispatchHits(const QAbstractRayCaster::Hits &hits); private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; void notifyJob(); QAbstractRayCasterPrivate::RayCasterType m_type = QAbstractRayCasterPrivate::WorldSpaceRayCaster; diff --git a/tests/auto/render/raycaster/tst_raycaster.cpp b/tests/auto/render/raycaster/tst_raycaster.cpp index 4d30c6d45..357517f0d 100644 --- a/tests/auto/render/raycaster/tst_raycaster.cpp +++ b/tests/auto/render/raycaster/tst_raycaster.cpp @@ -44,6 +44,7 @@ private Q_SLOTS: void checkPeerPropertyMirroring() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::RayCaster rayCaster; Qt3DRender::QRayCaster caster; caster.setRunMode(Qt3DRender::QRayCaster::Continuous); @@ -52,7 +53,8 @@ private Q_SLOTS: caster.setLength(42.f); // WHEN - simulateInitialization(&caster, &rayCaster); + rayCaster.setRenderer(&renderer); + simulateInitializationSync(&caster, &rayCaster); // THEN QVERIFY(!rayCaster.peerId().isNull()); @@ -65,6 +67,7 @@ private Q_SLOTS: void checkInitialAndCleanedUpState() { // GIVEN + TestRenderer renderer; Qt3DRender::Render::RayCaster rayCaster; // THEN @@ -76,7 +79,8 @@ private Q_SLOTS: caster.setRunMode(Qt3DRender::QRayCaster::Continuous); // WHEN - simulateInitialization(&caster, &rayCaster); + rayCaster.setRenderer(&renderer); + simulateInitializationSync(&caster, &rayCaster); rayCaster.cleanup(); // THEN @@ -88,14 +92,14 @@ private Q_SLOTS: // GIVEN TestRenderer renderer; { + Qt3DRender::QRayCaster caster; Qt3DRender::Render::RayCaster rayCaster; rayCaster.setRenderer(&renderer); + simulateInitializationSync(&caster, &rayCaster); // WHEN - Qt3DCore::QPropertyUpdatedChangePtr updateChange(new Qt3DCore::QPropertyUpdatedChange(Qt3DCore::QNodeId())); - updateChange->setValue(Qt3DRender::QRayCaster::Continuous); - updateChange->setPropertyName("runMode"); - rayCaster.sceneChangeEvent(updateChange); + caster.setRunMode(Qt3DRender::QRayCaster::Continuous); + rayCaster.syncFromFrontEnd(&caster, false); // THEN QCOMPARE(rayCaster.runMode(), Qt3DRender::QRayCaster::Continuous); -- cgit v1.2.3 From bd3aa578b8d822840fc3d4a6ef819b29b2c26034 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 5 Sep 2019 13:49:19 +0200 Subject: Doc: Fix documentation issues for Qt3DRender::QTexture* classes Fixes: QTWEBSITE-878 Change-Id: I8a4ac1de75dfb8ec4ff784a01d3e4abbc031a7ba Reviewed-by: Venugopal Shivashankar --- src/render/texture/qtexture.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp index 0e652c6ff..59857ea53 100644 --- a/src/render/texture/qtexture.cpp +++ b/src/render/texture/qtexture.cpp @@ -1036,6 +1036,7 @@ void TextureDownloadRequest::onCompleted() /*! \class Qt3DRender::QTexture1D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target1D target format. @@ -1056,6 +1057,7 @@ QTexture1D::~QTexture1D() /*! \class Qt3DRender::QTexture1DArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target1DArray target format. @@ -1076,6 +1078,7 @@ QTexture1DArray::~QTexture1DArray() /*! \class Qt3DRender::QTexture2D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2D target format. @@ -1096,6 +1099,7 @@ QTexture2D::~QTexture2D() /*! \class Qt3DRender::QTexture2DArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DArray target format. @@ -1116,6 +1120,7 @@ QTexture2DArray::~QTexture2DArray() /*! \class Qt3DRender::QTexture3D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target3D target format. @@ -1136,6 +1141,7 @@ QTexture3D::~QTexture3D() /*! \class Qt3DRender::QTextureCubeMap + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetCubeMap target format. @@ -1156,6 +1162,7 @@ QTextureCubeMap::~QTextureCubeMap() /*! \class Qt3DRender::QTextureCubeMapArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetCubeMapArray target format. @@ -1176,6 +1183,7 @@ QTextureCubeMapArray::~QTextureCubeMapArray() /*! \class Qt3DRender::QTexture2DMultisample + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DMultisample target format. @@ -1196,6 +1204,7 @@ QTexture2DMultisample::~QTexture2DMultisample() /*! \class Qt3DRender::QTexture2DMultisampleArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DMultisampleArray target format. @@ -1216,6 +1225,7 @@ QTexture2DMultisampleArray::~QTexture2DMultisampleArray() /*! \class Qt3DRender::QTextureRectangle + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetRectangle target format. @@ -1236,6 +1246,7 @@ QTextureRectangle::~QTextureRectangle() /*! \class Qt3DRender::QTextureBuffer + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetBuffer target format. @@ -1275,6 +1286,7 @@ void QTextureLoaderPrivate::updateGenerator() /*! \class Qt3DRender::QTextureLoader + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \brief Handles the texture loading and setting the texture's properties. */ @@ -1488,7 +1500,9 @@ bool QTextureFromSourceGenerator::isMirrored() const } /*! - * \class QSharedGLTexture + * \class Qt3DRender::QSharedGLTexture + * \inmodule Qt3DRender + * \inheaderfile Qt3DRender/QTexture * \brief Allows to use a textureId from a separate OpenGL context in a Qt 3D scene. * * Depending on the rendering mode used by Qt 3D, the shared context will either be: @@ -1515,6 +1529,14 @@ bool QTextureFromSourceGenerator::isMirrored() const * specify the correct sampler type to be used. */ +/*! + \qmltype SharedGLTexture + \instantiates Qt3DRender::QSharedGLTexture + \inqmlmodule Qt3D.Render + \brief Allows to use a textureId from a separate OpenGL context in a Qt 3D scene. + \since 5.13 +*/ + QSharedGLTexture::QSharedGLTexture(Qt3DCore::QNode *parent) : QAbstractTexture(parent) { @@ -1527,7 +1549,7 @@ QSharedGLTexture::~QSharedGLTexture() } /*! - * \qmlproperty textureId + * \qmlproperty int SharedGLTexture::textureId * * The OpenGL texture id value that you want Qt3D to gain access to. */ -- cgit v1.2.3 From 4bae053c5dd756444c415bd6ddb121f7e3873b83 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Mon, 12 Aug 2019 13:00:28 +0200 Subject: RenderView:buildDrawRenderCommands: only set Command members that matter Some values where overridden in Renderer::prepareSubmission so no point in spending time setting them in the first place Change-Id: Iceea0cbe044b883d0797aebd7487f8f6b29ac542 Reviewed-by: Mike Krus --- .../renderers/opengl/renderer/rendercommand_p.h | 4 +- src/render/renderers/opengl/renderer/renderer.cpp | 11 ++--- .../renderers/opengl/renderer/renderview.cpp | 54 ++-------------------- 3 files changed, 10 insertions(+), 59 deletions(-) diff --git a/src/render/renderers/opengl/renderer/rendercommand_p.h b/src/render/renderers/opengl/renderer/rendercommand_p.h index 67e02d35b..61cc6d17d 100644 --- a/src/render/renderers/opengl/renderer/rendercommand_p.h +++ b/src/render/renderers/opengl/renderer/rendercommand_p.h @@ -89,7 +89,7 @@ public: // A QAttribute pack might be interesting // This is a temporary fix in the meantime, to remove the hacked methods in Technique - QVector m_attributes; + QVector m_activeAttributes; float m_depth; int m_changeCost; @@ -103,7 +103,7 @@ public: CommandType m_type; int m_workGroups[3]; - // Values filled for draw calls + // Values filled for draw calls by Renderer (in prepare Submission) GLsizei m_primitiveCount; QGeometryRenderer::PrimitiveType m_primitiveType; int m_restartIndexValue; diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index a05e128a2..af9a6e7e6 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -896,7 +896,7 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView if (rGeometry->isDirty()) m_dirtyGeometry.push_back(rGeometry); - if (!command->m_attributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) { + if (!command->m_activeAttributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) { Profiling::GLTimeRecorder recorder(Profiling::VAOUpload); // Activate shader m_submissionContext->activateShader(shader->dna()); @@ -918,9 +918,8 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView // Prepare the ShaderParameterPack based on the active uniforms of the shader shader->prepareUniforms(command->m_parameterPack); - // TO DO: The step below could be performed by the RenderCommand builder job { // Scoped to show extent - command->m_isValid = !command->m_attributes.empty(); + command->m_isValid = !command->m_activeAttributes.empty(); if (!command->m_isValid) continue; @@ -941,7 +940,7 @@ void Renderer::prepareCommandsSubmission(const QVector &renderView indirectAttribute = attribute; break; case QAttribute::VertexAttribute: { - if (command->m_attributes.contains(attribute->nameId())) + if (command->m_activeAttributes.contains(attribute->nameId())) estimatedCount = qMax(attribute->count(), estimatedCount); break; } @@ -2174,7 +2173,7 @@ bool Renderer::updateVAOWithAttributes(Geometry *geometry, if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate) m_submissionContext->specifyIndices(buffer); // Vertex Attribute - } else if (command->m_attributes.contains(attribute->nameId())) { + } else if (command->m_activeAttributes.contains(attribute->nameId())) { if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate) { // Find the location for the attribute const QVector shaderAttributes = shader->attributes(); @@ -2219,7 +2218,7 @@ bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry, continue; if ((attribute->attributeType() == QAttribute::IndexAttribute && attribute->isDirty()) || - (command->m_attributes.contains(attribute->nameId()) && attribute->isDirty())) + (command->m_activeAttributes.contains(attribute->nameId()) && attribute->isDirty())) return true; } return false; diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index b00f2c473..420b32325 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -632,21 +632,18 @@ QVector RenderView::buildDrawRenderCommands(const QVectorcomponentUuid(); const HMaterial materialHandle = entity->componentHandle(); const QVector renderPassData = m_parameters.value(materialComponentId); - HGeometry geometryHandle = m_manager->lookupHandle(geometryRenderer->geometryId()); - Geometry *geometry = m_manager->data(geometryHandle); // 1 RenderCommand per RenderPass pass on an Entity with a Mesh for (const RenderPassParameterData &passData : renderPassData) { // Add the RenderPass Parameters RenderCommand *command = new RenderCommand(); + command->m_geometryRenderer = geometryRendererHandle; + command->m_geometry = m_manager->geometryManager()->lookupHandle(geometryRenderer->geometryId()); // Project the camera-to-object-center vector onto the camera // view vector. This gives a depth value suitable as the key // for BackToFront sorting. command->m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir); - - command->m_geometry = geometryHandle; - command->m_geometryRenderer = geometryRendererHandle; command->m_material = materialHandle; // For RenderPass based states we use the globally set RenderState // if no renderstates are defined as part of the pass. That means: @@ -686,51 +683,6 @@ QVector RenderView::buildDrawRenderCommands(const QVectorm_isValid = !command->m_attributes.empty(); - if (command->m_isValid) { - // Update the draw command with what's going to be needed for the drawing - uint primitiveCount = geometryRenderer->vertexCount(); - uint estimatedCount = 0; - Attribute *indexAttribute = nullptr; - - const QVector attributeIds = geometry->attributes(); - for (Qt3DCore::QNodeId attributeId : attributeIds) { - Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId); - if (attribute->attributeType() == QAttribute::IndexAttribute) - indexAttribute = attribute; - else if (command->m_attributes.contains(attribute->nameId())) - estimatedCount = qMax(attribute->count(), estimatedCount); - } - - // Update the draw command with all the information required for the drawing - command->m_drawIndexed = (indexAttribute != nullptr); - if (command->m_drawIndexed) { - command->m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType()); - command->m_indexAttributeByteOffset = indexAttribute->byteOffset(); - } - - // Use the count specified by the GeometryRender - // If not specified use the indexAttribute count if present - // Otherwise tries to use the count from the attribute with the highest count - if (primitiveCount == 0) { - if (indexAttribute) - primitiveCount = indexAttribute->count(); - else - primitiveCount = estimatedCount; - } - - command->m_primitiveCount = primitiveCount; - command->m_primitiveType = geometryRenderer->primitiveType(); - command->m_primitiveRestartEnabled = geometryRenderer->primitiveRestartEnabled(); - command->m_restartIndexValue = geometryRenderer->restartIndexValue(); - command->m_firstInstance = geometryRenderer->firstInstance(); - command->m_instanceCount = geometryRenderer->instanceCount(); - command->m_firstVertex = geometryRenderer->firstVertex(); - command->m_indexOffset = geometryRenderer->indexOffset(); - command->m_verticesPerPatch = geometryRenderer->verticesPerPatch(); - } - commands.append(command); } } @@ -1049,7 +1001,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, // Set default attributes for (const int attributeNameId : attributeNamesIds) - command->m_attributes.push_back(attributeNameId); + command->m_activeAttributes.push_back(attributeNameId); // Parameters remaining could be // -> uniform scalar / vector -- cgit v1.2.3 From c40cccb0b4485045db61c2d4e825e33a68c58861 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Fri, 27 Sep 2019 15:09:00 +0100 Subject: Reset input axis changes when enabling camera controller When input axis are enabled or disable, we now reset the value to 0. And enabling or disabling the camera controller, we now do the same for the axis. This prevents residual movement when re-enabling the controller due to the asynchronous updates. Task-number: QTBUG-77996 Change-Id: I5ac016d5b708e1f8d8eaa996bbd28c00c0f05e79 Reviewed-by: Paul Lemire --- src/extras/defaults/qabstractcameracontroller.cpp | 4 ++++ src/input/frontend/qaxis.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/extras/defaults/qabstractcameracontroller.cpp b/src/extras/defaults/qabstractcameracontroller.cpp index 27df65d7b..c8ebf42f3 100644 --- a/src/extras/defaults/qabstractcameracontroller.cpp +++ b/src/extras/defaults/qabstractcameracontroller.cpp @@ -211,6 +211,10 @@ void QAbstractCameraControllerPrivate::init() m_logicalDevice, &Qt3DInput::QLogicalDevice::setEnabled); QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, m_frameAction, &Qt3DLogic::QFrameAction::setEnabled); + for (auto axis: {m_rxAxis, m_ryAxis, m_txAxis, m_tyAxis, m_tzAxis}) { + QObject::connect(q, &Qt3DCore::QEntity::enabledChanged, + axis, &Qt3DInput::QAxis::setEnabled); + } QObject::connect(m_escapeButtonAction, &Qt3DInput::QAction::activeChanged, q, [this](bool isActive) { diff --git a/src/input/frontend/qaxis.cpp b/src/input/frontend/qaxis.cpp index 01e28e9cf..1830c8005 100644 --- a/src/input/frontend/qaxis.cpp +++ b/src/input/frontend/qaxis.cpp @@ -83,6 +83,10 @@ namespace Qt3DInput { QAxis::QAxis(Qt3DCore::QNode *parent) : Qt3DCore::QNode(*new QAxisPrivate(), parent) { + Q_D(QAxis); + connect(this, &QAxis::enabledChanged, [d]() { + d->setValue(0.); + }); } /*! \internal */ -- cgit v1.2.3 From bb89fc9823eca1eca41dab1ef8ceb12beeab96d3 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 25 Sep 2019 15:23:30 +0200 Subject: Renderer: cache traversal of FrameGraph Will be retraversed only when something in the FrameGraph has changed Change-Id: Ibb43f8f2928b10a584f468fb13f1d4773c7fcebb Reviewed-by: Mike Krus --- src/render/renderers/opengl/renderer/renderer.cpp | 35 ++++++++++---------- src/render/renderers/opengl/renderer/renderer_p.h | 2 ++ tests/auto/render/renderer/tst_renderer.cpp | 39 ++++++++++++----------- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index af9a6e7e6..66d404f4e 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -1824,26 +1824,27 @@ QVector Renderer::renderBinJobs() // populate the RenderView with a set of RenderCommands that get // their details from the RenderNodes that are visible to the // Camera selected by the framegraph configuration - FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); - const QVector fgLeaves = visitor.traverse(frameGraphRoot()); - - // Handle single shot subtree enablers - const auto subtreeEnablers = visitor.takeEnablersToDisable(); - for (auto *node : subtreeEnablers) - m_updatedDisables.push_back(node->peerId()); - if (m_updatedDisables.size() > 0) - renderBinJobs.push_back(m_sendDisablesToFrontendJob); - - // Remove leaf nodes that no longer exist from cache - const QList keys = m_cache.leafNodeCache.keys(); - for (FrameGraphNode *leafNode : keys) { - if (!fgLeaves.contains(leafNode)) - m_cache.leafNodeCache.remove(leafNode); + if (frameGraphDirty) { + FrameGraphVisitor visitor(m_nodesManager->frameGraphManager()); + m_frameGraphLeaves = visitor.traverse(frameGraphRoot()); + // Remove leaf nodes that no longer exist from cache + const QList keys = m_cache.leafNodeCache.keys(); + for (FrameGraphNode *leafNode : keys) { + if (!m_frameGraphLeaves.contains(leafNode)) + m_cache.leafNodeCache.remove(leafNode); + } + + // Handle single shot subtree enablers + const auto subtreeEnablers = visitor.takeEnablersToDisable(); + for (auto *node : subtreeEnablers) + m_updatedDisables.push_back(node->peerId()); + if (m_updatedDisables.size() > 0) + renderBinJobs.push_back(m_sendDisablesToFrontendJob); } - const int fgBranchCount = fgLeaves.size(); + const int fgBranchCount = m_frameGraphLeaves.size(); for (int i = 0; i < fgBranchCount; ++i) { - RenderViewBuilder builder(fgLeaves.at(i), i, this); + RenderViewBuilder builder(m_frameGraphLeaves.at(i), i, this); builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt); builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty); builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index 0ea27d91a..c7b4f8805 100644 --- a/src/render/renderers/opengl/renderer/renderer_p.h +++ b/src/render/renderers/opengl/renderer/renderer_p.h @@ -424,6 +424,8 @@ private: QMetaObject::Connection m_contextConnection; RendererCache m_cache; bool m_shouldSwapBuffers; + + QVector m_frameGraphLeaves; }; } // namespace Render diff --git a/tests/auto/render/renderer/tst_renderer.cpp b/tests/auto/render/renderer/tst_renderer.cpp index 973192d6a..e1bf8dfd9 100644 --- a/tests/auto/render/renderer/tst_renderer.cpp +++ b/tests/auto/render/renderer/tst_renderer.cpp @@ -36,6 +36,7 @@ #include #include #include +#include class tst_Renderer : public QObject { @@ -170,9 +171,24 @@ private Q_SLOTS: // syncRenderViewCommandBuilderJob // n * (RenderViewCommandBuildJobs) - // WHEN (nothing dirty, no buffers, no layers to be rebuilt, no materials to be rebuilt) + // WHEN QVector jobs = renderer.renderBinJobs(); + // THEN + QCOMPARE(jobs.size(), + 1 + // updateLevelOfDetailJob + 1 + // cleanupJob + 1 + // VAOGatherer + 1 + // updateSkinningPaletteJob + 1); // SyncLoadingJobs + + renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); + renderQueue->reset(); + + // WHEN (nothing dirty, no buffers, no layers to be rebuilt, no materials to be rebuilt) + renderer.markDirty(Qt3DRender::Render::AbstractRenderer::FrameGraphDirty, nullptr); + jobs = renderer.renderBinJobs(); + // THEN (level QCOMPARE(jobs.size(), 1 + // updateLevelOfDetailJob @@ -180,7 +196,9 @@ private Q_SLOTS: 1 + // VAOGatherer 1 + // updateSkinningPaletteJob 1 + // SyncLoadingJobs - singleRenderViewJobCount); // Only valid for the first call to renderBinJobs(), since subsequent calls won't have the renderqueue reset + singleRenderViewJobCount + + renderViewBuilderMaterialCacheJobCount + + layerCacheJobCount); renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); renderQueue->reset(); @@ -297,23 +315,6 @@ private Q_SLOTS: renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); renderQueue->reset(); - // WHEN - renderer.markDirty(Qt3DRender::Render::AbstractRenderer::FrameGraphDirty, nullptr); - jobs = renderer.renderBinJobs(); - - QCOMPARE(jobs.size(), - 1 + // updateLevelOfDetailJob - 1 + // cleanupJob - 1 + // VAOGatherer - 1 + // updateSkinningPaletteJob - 1 + // SyncLoadingJobs - singleRenderViewJobCount + - layerCacheJobCount + - renderViewBuilderMaterialCacheJobCount); - - renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty); - renderQueue->reset(); - // WHEN renderer.markDirty(Qt3DRender::Render::AbstractRenderer::AllDirty, nullptr); jobs = renderer.renderBinJobs(); -- cgit v1.2.3 From 0f459409785d672ac65752d27f08f213bcbfc55a Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Mon, 30 Sep 2019 08:02:05 +0200 Subject: Renderer: remove redundant setter call Change-Id: I3829f621958d98b50563a2a8ed782aec1a7ceb65 Reviewed-by: Mike Krus --- src/render/renderers/opengl/renderer/renderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp index 66d404f4e..45f13c424 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -1850,8 +1850,6 @@ QVector Renderer::renderBinJobs() builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt); - builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty); - builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); builder.prepareJobs(); -- cgit v1.2.3 From fc668c2e895953d60a22e0a09071876f395f3e28 Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 27 Sep 2019 14:36:31 +0200 Subject: RenderSurfaceSelector: record window size instead of accessing it Avoids having to lock the window (which in case we are rendering in parallel can block for several ms) Change-Id: I9999cee52d8b07a9317d9761c546a08f98681924 Reviewed-by: Mike Krus --- src/render/framegraph/rendersurfaceselector.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/render/framegraph/rendersurfaceselector.cpp b/src/render/framegraph/rendersurfaceselector.cpp index 173da77d6..ed8a79eac 100644 --- a/src/render/framegraph/rendersurfaceselector.cpp +++ b/src/render/framegraph/rendersurfaceselector.cpp @@ -122,12 +122,7 @@ QSize RenderSurfaceSelector::renderTargetSize() const { if (m_renderTargetSize.isValid()) return m_renderTargetSize; - { - SurfaceLocker lock(m_surface); - if (lock.isSurfaceValid() && m_surface && m_surface->size().isValid()) - return m_surface->size(); - } - return QSize(); + return QSize(m_width, m_height); } } // namespace Render -- cgit v1.2.3 From 5c16cd7be2ba8bd6d98ee18305dd7d69a9f873ca Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Fri, 27 Sep 2019 15:45:54 +0100 Subject: Enable direct syncing on input aspect Requires adding new intermediate base class. Will update classes as the functionality is introduced since the static casting is not called unless the class supports syncing. Change-Id: I157c76ae520c1c9e49d46e22f063b7738bbec707 Reviewed-by: Paul Lemire --- src/input/backend/backend.pri | 2 + src/input/backend/backendnode.cpp | 74 ++++++++++++++++++++++++++++++++++ src/input/backend/backendnode_p.h | 79 +++++++++++++++++++++++++++++++++++++ src/input/frontend/qinputaspect.cpp | 8 ++++ src/input/frontend/qinputaspect_p.h | 1 + 5 files changed, 164 insertions(+) create mode 100644 src/input/backend/backendnode.cpp create mode 100644 src/input/backend/backendnode_p.h diff --git a/src/input/backend/backend.pri b/src/input/backend/backend.pri index 71c1a9a1c..e1ddee9c7 100644 --- a/src/input/backend/backend.pri +++ b/src/input/backend/backend.pri @@ -1,4 +1,5 @@ HEADERS += \ + $$PWD/backendnode_p.h \ $$PWD/keyboarddevice_p.h \ $$PWD/keyboardhandler_p.h \ $$PWD/inputhandler_p.h \ @@ -39,6 +40,7 @@ HEADERS += \ $$PWD/axisaccumulatorjob_p.h SOURCES += \ + $$PWD/backendnode.cpp \ $$PWD/keyboarddevice.cpp \ $$PWD/keyboardhandler.cpp \ $$PWD/inputhandler.cpp \ diff --git a/src/input/backend/backendnode.cpp b/src/input/backend/backendnode.cpp new file mode 100644 index 000000000..aa440ed51 --- /dev/null +++ b/src/input/backend/backendnode.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "backendnode_p.h" +#include +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { +namespace Input { + +BackendNode::BackendNode(Mode mode) + : Qt3DCore::QBackendNode(mode) +{ +} + +BackendNode::BackendNode(Qt3DCore::QBackendNodePrivate &dd) + : Qt3DCore::QBackendNode(dd) +{ + +} + +BackendNode::~BackendNode() +{ +} + +void BackendNode::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) +{ + Q_UNUSED(firstTime) + + d_ptr->setEnabled(frontEnd->isEnabled()); +} + +} // namespace Input +} // namespace Qt3DInput + +QT_END_NAMESPACE diff --git a/src/input/backend/backendnode_p.h b/src/input/backend/backendnode_p.h new file mode 100644 index 000000000..a7749852b --- /dev/null +++ b/src/input/backend/backendnode_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 QT3DINPUT_INPUT_BACKENDNODE_H +#define QT3DINPUT_INPUT_BACKENDNODE_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 +#include + +QT_BEGIN_NAMESPACE + +namespace Qt3DInput { +namespace Input { + +class Q_3DINPUTSHARED_PRIVATE_EXPORT BackendNode : public Qt3DCore::QBackendNode +{ +public: + BackendNode(Qt3DCore::QBackendNode::Mode mode = ReadOnly); + ~BackendNode(); + + virtual void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime); + +protected: + explicit BackendNode(Qt3DCore::QBackendNodePrivate &dd); +}; + +} // namespace Input +} // namespace Qt3DInput + +QT_END_NAMESPACE + +#endif // QT3DINPUT_INPUT_BACKENDNODE_H diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp index e7ff70326..e91e545bb 100644 --- a/src/input/frontend/qinputaspect.cpp +++ b/src/input/frontend/qinputaspect.cpp @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -109,6 +110,13 @@ QInputAspectPrivate::QInputAspectPrivate() { } +void QInputAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const +{ + Input::BackendNode *renderBackend = static_cast(backend); + renderBackend->syncFromFrontEnd(node, firstTime); +} + + /*! \class Qt3DInput::QInputAspect \inherits Qt3DCore::QAbstractAspect diff --git a/src/input/frontend/qinputaspect_p.h b/src/input/frontend/qinputaspect_p.h index bcdd8d4ed..aee7e7909 100644 --- a/src/input/frontend/qinputaspect_p.h +++ b/src/input/frontend/qinputaspect_p.h @@ -69,6 +69,7 @@ class QInputAspectPrivate : public Qt3DCore::QAbstractAspectPrivate public: QInputAspectPrivate(); void loadInputDevicePlugins(); + void syncDirtyFrontEndNode(Qt3DCore::QNode *node, Qt3DCore::QBackendNode *backend, bool firstTime) const override; Q_DECLARE_PUBLIC(QInputAspect) QScopedPointer m_inputHandler; -- cgit v1.2.3 From 621c19719e51d0b4c94a51f802f8a2128e201b85 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Fri, 27 Sep 2019 16:28:34 +0100 Subject: Update QAxis to use direct sync Change-Id: Id159885d3c3ef4f2582a7b308350c6b43182f521 Reviewed-by: Paul Lemire --- src/input/backend/axis.cpp | 41 ++++++++++-------------------------- src/input/backend/axis_p.h | 8 +++---- src/input/frontend/qaxis.cpp | 13 ++---------- src/input/frontend/qinputaspect.cpp | 2 +- tests/auto/input/axis/tst_axis.cpp | 25 ++++++++++------------ tests/auto/input/qaxis/tst_qaxis.cpp | 18 ++++++---------- 6 files changed, 35 insertions(+), 72 deletions(-) diff --git a/src/input/backend/axis.cpp b/src/input/backend/axis.cpp index 6ba4e2b34..20c05a49f 100644 --- a/src/input/backend/axis.cpp +++ b/src/input/backend/axis.cpp @@ -42,10 +42,9 @@ #include #include #include -#include -#include #include +#include QT_BEGIN_NAMESPACE @@ -54,18 +53,11 @@ namespace Qt3DInput { namespace Input { Axis::Axis() - : Qt3DCore::QBackendNode(ReadWrite) + : BackendNode(ReadWrite) , m_axisValue(0.0f) { } -void Axis::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) -{ - const auto typedChange = qSharedPointerCast>(change); - const auto &data = typedChange->data; - m_inputs = data.inputIds; -} - void Axis::cleanup() { QBackendNode::setEnabled(false); @@ -75,11 +67,11 @@ void Axis::cleanup() void Axis::setAxisValue(float axisValue) { - if (isEnabled() && (axisValue != m_axisValue)) { + if (isEnabled() && (!qFuzzyCompare(axisValue, m_axisValue))) { m_axisValue = axisValue; // Send a change to the frontend - auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); // TODOSYNC replace with direct access e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); e->setPropertyName("value"); e->setValue(m_axisValue); @@ -87,26 +79,15 @@ void Axis::setAxisValue(float axisValue) } } -void Axis::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) +void Axis::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) { - switch (e->type()) { - case Qt3DCore::PropertyValueAdded: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("input")) - m_inputs.push_back(change->addedNodeId()); - break; - } + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + const Qt3DInput::QAxis *node = qobject_cast(frontEnd); + if (!node) + return; - case Qt3DCore::PropertyValueRemoved: { - const auto change = qSharedPointerCast(e); - if (change->propertyName() == QByteArrayLiteral("input")) - m_inputs.removeOne(change->removedNodeId()); - } - - default: - break; - } - QBackendNode::sceneChangeEvent(e); + auto ids = Qt3DCore::qIdsForNodes(node->inputs()); + m_inputs = ids; } } // namespace Input diff --git a/src/input/backend/axis_p.h b/src/input/backend/axis_p.h index b83405060..da4ec9ac6 100644 --- a/src/input/backend/axis_p.h +++ b/src/input/backend/axis_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include +#include #include QT_BEGIN_NAMESPACE @@ -60,7 +60,7 @@ namespace Qt3DInput { namespace Input { -class Q_AUTOTEST_EXPORT Axis : public Qt3DCore::QBackendNode +class Q_AUTOTEST_EXPORT Axis : public BackendNode { public: Axis(); @@ -68,11 +68,9 @@ public: inline QVector inputs() const { return m_inputs; } inline float axisValue() const { return m_axisValue; } void setAxisValue(float axisValue); - void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; + void syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) override; private: - void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) final; - QVector m_inputs; float m_axisValue; }; diff --git a/src/input/frontend/qaxis.cpp b/src/input/frontend/qaxis.cpp index 1830c8005..082ad4f67 100644 --- a/src/input/frontend/qaxis.cpp +++ b/src/input/frontend/qaxis.cpp @@ -117,12 +117,7 @@ void QAxis::addInput(QAbstractAxisInput *input) // Ensures proper bookkeeping d->registerDestructionHelper(input, &QAxis::removeInput, d->m_inputs); - - if (d->m_changeArbiter != nullptr) { - const auto change = Qt3DCore::QPropertyNodeAddedChangePtr::create(id(), input); - change->setPropertyName("input"); - d->notifyObservers(change); - } + d->update(); } } @@ -144,11 +139,7 @@ void QAxis::removeInput(QAbstractAxisInput *input) Q_D(QAxis); if (d->m_inputs.contains(input)) { - if (d->m_changeArbiter != nullptr) { - const auto change = Qt3DCore::QPropertyNodeRemovedChangePtr::create(id(), input); - change->setPropertyName("input"); - d->notifyObservers(change); - } + d->update(); d->m_inputs.removeOne(input); diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp index e91e545bb..c063f2580 100644 --- a/src/input/frontend/qinputaspect.cpp +++ b/src/input/frontend/qinputaspect.cpp @@ -149,7 +149,7 @@ QInputAspect::QInputAspect(QInputAspectPrivate &dd, QObject *parent) registerBackendType(QBackendNodeMapperPtr(new Input::KeyboardHandlerFunctor(d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeMapperPtr(new Input::MouseDeviceFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType(QBackendNodeMapperPtr(new Input::MouseHandlerFunctor(d_func()->m_inputHandler.data()))); - registerBackendType(QBackendNodeMapperPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisManager()))); + registerBackendType(QBackendNodeMapperPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisManager()))); registerBackendType(QBackendNodeMapperPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->axisAccumulatorManager()))); registerBackendType(QBackendNodeMapperPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->analogAxisInputManager()))); registerBackendType(QBackendNodeMapperPtr(new Input::InputNodeFunctor(d_func()->m_inputHandler->buttonAxisInputManager()))); diff --git a/tests/auto/input/axis/tst_axis.cpp b/tests/auto/input/axis/tst_axis.cpp index 42f7f56fc..8ad8098af 100644 --- a/tests/auto/input/axis/tst_axis.cpp +++ b/tests/auto/input/axis/tst_axis.cpp @@ -65,7 +65,7 @@ private Q_SLOTS: axis.addInput(&axisInput); // WHEN - simulateInitialization(&axis, &backendAxis); + simulateInitializationSync(&axis, &backendAxis); // THEN QCOMPARE(backendAxis.peerId(), axis.id()); @@ -97,7 +97,7 @@ private Q_SLOTS: axis.addInput(&axisInput); // WHEN - simulateInitialization(&axis, &backendAxis); + simulateInitializationSync(&axis, &backendAxis); backendAxis.setAxisValue(883.0f); backendAxis.cleanup(); @@ -110,33 +110,30 @@ private Q_SLOTS: void checkPropertyChanges() { // GIVEN + Qt3DInput::QAxis axis; Qt3DInput::Input::Axis backendAxis; - Qt3DCore::QPropertyUpdatedChangePtr updateChange; + simulateInitializationSync(&axis, &backendAxis); // WHEN - updateChange = QSharedPointer::create(Qt3DCore::QNodeId()); - updateChange->setPropertyName("enabled"); - updateChange->setValue(true); - backendAxis.sceneChangeEvent(updateChange); + axis.setEnabled(false); + backendAxis.syncFromFrontEnd(&axis, false); // THEN - QCOMPARE(backendAxis.isEnabled(), true); + QCOMPARE(backendAxis.isEnabled(), false); // WHEN DummyAxisInput input; const Qt3DCore::QNodeId inputId = input.id(); - const auto nodeAddedChange = Qt3DCore::QPropertyNodeAddedChangePtr::create(Qt3DCore::QNodeId(), &input); - nodeAddedChange->setPropertyName("input"); - backendAxis.sceneChangeEvent(nodeAddedChange); + axis.addInput(&input); + backendAxis.syncFromFrontEnd(&axis, false); // THEN QCOMPARE(backendAxis.inputs().size(), 1); QCOMPARE(backendAxis.inputs().first(), inputId); // WHEN - const auto nodeRemovedChange = Qt3DCore::QPropertyNodeRemovedChangePtr::create(Qt3DCore::QNodeId(), &input); - nodeRemovedChange->setPropertyName("input"); - backendAxis.sceneChangeEvent(nodeRemovedChange); + axis.removeInput(&input); + backendAxis.syncFromFrontEnd(&axis, false); // THEN QCOMPARE(backendAxis.inputs().size(), 0); diff --git a/tests/auto/input/qaxis/tst_qaxis.cpp b/tests/auto/input/qaxis/tst_qaxis.cpp index 35cee0bba..03ddcb76d 100644 --- a/tests/auto/input/qaxis/tst_qaxis.cpp +++ b/tests/auto/input/qaxis/tst_qaxis.cpp @@ -113,24 +113,20 @@ private Q_SLOTS: QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - Qt3DCore::QPropertyNodeAddedChangePtr change = arbiter.events.first().staticCast(); - QCOMPARE(change->propertyName(), "input"); - QCOMPARE(change->addedNodeId(), input->id()); - QCOMPARE(change->type(), Qt3DCore::PropertyValueAdded); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(arbiter.dirtyNodes.size(), 1); + QCOMPARE(arbiter.dirtyNodes.front(), axis.data()); - arbiter.events.clear(); + arbiter.dirtyNodes.clear(); // WHEN axis->removeInput(input); QCoreApplication::processEvents(); // THEN - QCOMPARE(arbiter.events.size(), 1); - Qt3DCore::QPropertyNodeRemovedChangePtr nodeRemovedChange = arbiter.events.first().staticCast(); - QCOMPARE(nodeRemovedChange->propertyName(), "input"); - QCOMPARE(nodeRemovedChange->removedNodeId(), input->id()); - QCOMPARE(nodeRemovedChange->type(), Qt3DCore::PropertyValueRemoved); + QCOMPARE(arbiter.events.size(), 0); + QCOMPARE(arbiter.dirtyNodes.size(), 1); + QCOMPARE(arbiter.dirtyNodes.front(), axis.data()); arbiter.events.clear(); } -- cgit v1.2.3