diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-01 03:00:42 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-01 03:00:42 +0200 |
commit | 73bfd21fcbe9f7f647edcbe19b7153ac4cc5c859 (patch) | |
tree | e814e94894d6974d93ac30eca21cbecf105d4ad9 | |
parent | 9ba07868d3ddedd2e39f9612118674cefd5fe1bf (diff) | |
parent | 621c19719e51d0b4c94a51f802f8a2128e201b85 (diff) |
Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: Ie15f601b175beeb01d00050dadf3cb8952ed580a
96 files changed, 1607 insertions, 1337 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/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/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 <Qt3DLogic/qlogicaspect.h> #include <Qt3DRender/qcamera.h> #include <QtGui/qopenglcontext.h> +#include <private/qrendersettings_p.h> #include <QEvent> @@ -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<Qt3DRender::QRenderSettingsPrivate *>( + Qt3DCore::QNodePrivate::get(d->m_renderSettings)); + p->invalidateFrame(); + } return QWindow::event(e); } 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 <Qt3DInput/qaxis.h> #include <Qt3DInput/qabstractaxisinput.h> #include <Qt3DCore/qpropertyupdatedchange.h> -#include <Qt3DCore/qpropertynodeaddedchange.h> -#include <Qt3DCore/qpropertynoderemovedchange.h> #include <Qt3DInput/private/qaxis_p.h> +#include <algorithm> 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<Qt3DCore::QNodeCreatedChange<QAxisData>>(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<Qt3DCore::QPropertyNodeAddedChange>(e); - if (change->propertyName() == QByteArrayLiteral("input")) - m_inputs.push_back(change->addedNodeId()); - break; - } + BackendNode::syncFromFrontEnd(frontEnd, firstTime); + const Qt3DInput::QAxis *node = qobject_cast<const Qt3DInput::QAxis *>(frontEnd); + if (!node) + return; - case Qt3DCore::PropertyValueRemoved: { - const auto change = qSharedPointerCast<Qt3DCore::QPropertyNodeRemovedChange>(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 <Qt3DCore/qbackendnode.h> +#include <Qt3DInput/private/backendnode_p.h> #include <Qt3DCore/qnodeid.h> 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<Qt3DCore::QNodeId> 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<Qt3DCore::QNodeId> m_inputs; float m_axisValue; }; 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 <Qt3DCore/qnode.h> +#include <Qt3DCore/private/qbackendnode_p.h> + +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 <Qt3DInput/private/qt3dinput_global_p.h> +#include <Qt3DCore/qbackendnode.h> + +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/qaxis.cpp b/src/input/frontend/qaxis.cpp index 01e28e9cf..082ad4f67 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 */ @@ -113,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(); } } @@ -140,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 e7ff70326..c063f2580 100644 --- a/src/input/frontend/qinputaspect.cpp +++ b/src/input/frontend/qinputaspect.cpp @@ -61,6 +61,7 @@ #include <QtCore/QLibraryInfo> #include <QtCore/QPluginLoader> +#include <Qt3DInput/private/backendnode_p.h> #include <Qt3DInput/private/action_p.h> #include <Qt3DInput/private/actioninput_p.h> #include <Qt3DInput/private/axis_p.h> @@ -109,6 +110,13 @@ QInputAspectPrivate::QInputAspectPrivate() { } +void QInputAspectPrivate::syncDirtyFrontEndNode(QNode *node, QBackendNode *backend, bool firstTime) const +{ + Input::BackendNode *renderBackend = static_cast<Input::BackendNode *>(backend); + renderBackend->syncFromFrontEnd(node, firstTime); +} + + /*! \class Qt3DInput::QInputAspect \inherits Qt3DCore::QAbstractAspect @@ -141,7 +149,7 @@ QInputAspect::QInputAspect(QInputAspectPrivate &dd, QObject *parent) registerBackendType<QKeyboardHandler>(QBackendNodeMapperPtr(new Input::KeyboardHandlerFunctor(d_func()->m_inputHandler.data()))); registerBackendType<QMouseDevice>(QBackendNodeMapperPtr(new Input::MouseDeviceFunctor(this, d_func()->m_inputHandler.data()))); registerBackendType<QMouseHandler>(QBackendNodeMapperPtr(new Input::MouseHandlerFunctor(d_func()->m_inputHandler.data()))); - registerBackendType<QAxis>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::Axis, Input::AxisManager>(d_func()->m_inputHandler->axisManager()))); + registerBackendType<QAxis, true>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::Axis, Input::AxisManager>(d_func()->m_inputHandler->axisManager()))); registerBackendType<QAxisAccumulator>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::AxisAccumulator, Input::AxisAccumulatorManager>(d_func()->m_inputHandler->axisAccumulatorManager()))); registerBackendType<QAnalogAxisInput>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::AnalogAxisInput, Input::AnalogAxisInputManager>(d_func()->m_inputHandler->analogAxisInputManager()))); registerBackendType<QButtonAxisInput>(QBackendNodeMapperPtr(new Input::InputNodeFunctor<Input::ButtonAxisInput, Input::ButtonAxisInputManager>(d_func()->m_inputHandler->buttonAxisInputManager()))); 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<Input::InputHandler> m_inputHandler; 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 <Qt3DRender/qcameralens.h> #include <Qt3DRender/private/nodemanagers_p.h> #include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/qcameralens_p.h> #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/entity_p.h> @@ -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<Qt3DCore::QNodeCreatedChange<QCameraLensData>>(change); - const auto &data = typedChange->data; - m_projection = Matrix4x4(data.projectionMatrix); - m_exposure = data.exposure; + const QCameraLens *node = qobject_cast<const QCameraLens *>(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<const QCameraLensPrivate *>(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<QNodeId>(); + computeSceneBoundingVolume({}, id, commandId); + } else if (m_pendingViewAllCommand.name == QLatin1String("QueryEntityBoundingVolume")) { + const QVector<QNodeId> ids = v.value<QVector<QNodeId>>(); + 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<float> 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<QPropertyUpdatedChange>(e); - - if (propertyChange->propertyName() == QByteArrayLiteral("projectionMatrix")) { - QMatrix4x4 projectionMatrix = propertyChange->value().value<QMatrix4x4>(); - m_projection = Matrix4x4(projectionMatrix); - } else if (propertyChange->propertyName() == QByteArrayLiteral("exposure")) { - setExposure(propertyChange->value().toFloat()); - } - - markDirty(AbstractRenderer::AllDirty); - } - break; - - case CommandRequested: { - QNodeCommandPtr command = qSharedPointerCast<QNodeCommand>(e); - - if (command->name() == QLatin1String("QueryRootBoundingVolume")) { - m_pendingViewAllCommand = command->commandId(); - QVariant v = command->data(); - QNodeId id = v.value<QNodeId>(); - computeSceneBoundingVolume({}, id, command->commandId()); - } else if (command->name() == QLatin1String("QueryEntityBoundingVolume")) { - m_pendingViewAllCommand = command->commandId(); - QVariant v = command->data(); - QVector<QNodeId> ids = v.value<QVector<QNodeId>>(); - 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 <Qt3DRender/private/backendnode_p.h> #include <Qt3DCore/private/qnodecommand_p.h> #include <Qt3DCore/private/matrix4x4_p.h> +#include <Qt3DRender/private/qcameralens_p.h> #include <QRectF> 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/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<Qt3DCore::QNodeCreatedChange<QComputeCommandData>>(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<const QComputeCommand *>(frontEnd); + if (!node) + return; -void ComputeCommand::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(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<QComputeCommand::RunType>(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<const QComputeCommandPrivate *>(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/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<QPropertyUpdatedChange>(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<const QLayer *>(frontEnd); + if (!node) + return; -void Layer::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) -{ - const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QLayerData>>(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/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 <Qt3DRender/private/qlevelofdetail_p.h> #include <Qt3DRender/private/stringtoint_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DRender/QCamera> #include <QVariant> 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<Qt3DCore::QNodeCreatedChange<QLevelOfDetailData>>(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<const QLevelOfDetail *>(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<QPropertyUpdatedChange>(e); - if (propertyChange->propertyName() == QByteArrayLiteral("currentIndex")) - m_currentIndex = propertyChange->value().value<int>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("camera")) - m_camera = propertyChange->value().value<Qt3DCore::QNodeId>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("thresholdType")) - m_thresholdType = propertyChange->value().value<QLevelOfDetail::ThresholdType>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("thresholds")) - m_thresholds = propertyChange->value().value<QVector<qreal>>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("volumeOverride")) - m_volumeOverride = propertyChange->value().value<Qt3DRender::QLevelOfDetailBoundingSphere>(); + 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/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<Qt3DCore::QNodeCreatedChange<QRenderSettingsData>>(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<const QRenderSettings *>(frontEnd); + if (!node) + return; -void RenderSettings::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == PropertyUpdated) { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(e); - if (propertyChange->propertyName() == QByteArrayLiteral("pickMethod")) - m_pickMethod = propertyChange->value().value<QPickingSettings::PickMethod>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("pickResult")) - m_pickResultMode = propertyChange->value().value<QPickingSettings::PickResultMode>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("faceOrientationPickingMode")) - m_faceOrientationPickingMode = propertyChange->value().value<QPickingSettings::FaceOrientationPickingMode>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("pickWorldSpaceTolerance")) - m_pickWorldSpaceTolerance = propertyChange->value().toFloat(); - else if (propertyChange->propertyName() == QByteArrayLiteral("activeFrameGraph")) - m_activeFrameGraph = propertyChange->value().value<QNodeId>(); - else if (propertyChange->propertyName() == QByteArrayLiteral("renderPolicy")) - m_renderPolicy = propertyChange->value().value<QRenderSettings::RenderPolicy>(); - markDirty(AbstractRenderer::AllDirty); - } else if (e->type() == CommandRequested) { - QNodeCommandPtr command = qSharedPointerCast<QNodeCommand>(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/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<Qt3DCore::QNodeCreatedChange<QRenderTargetData>>(change); - const auto &data = typedChange->data; - m_renderOutputs = data.outputIds; + const QRenderTarget *node = qobject_cast<const QRenderTarget *>(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<Qt3DCore::QNodeId> RenderTarget::renderOutputs() const return m_renderOutputs; } -void RenderTarget::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case Qt3DCore::PropertyValueAdded: { - const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(e); - if (change->propertyName() == QByteArrayLiteral("output")) { - appendRenderOutput(change->addedNodeId()); - markDirty(AbstractRenderer::AllDirty); - } - break; - } - - case Qt3DCore::PropertyValueRemoved: { - const auto change = qSharedPointerCast<QPropertyNodeRemovedChange>(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<Qt3DCore::QNodeId> 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<Qt3DCore::QNodeId> m_renderOutputs; }; 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<Qt3DCore::QNodeCreatedChange<QRenderTargetOutputData>>(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<const QRenderTargetOutput *>(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<QPropertyUpdatedChange>(e); - if (e->type() == PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("type")) { - m_attachmentData.m_point = static_cast<QRenderTargetOutput::AttachmentPoint>(propertyChange->value().toInt()); - } - else if (propertyChange->propertyName() == QByteArrayLiteral("texture")) { - m_attachmentData.m_textureUuid = propertyChange->value().value<QNodeId>(); - } - 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<QAbstractTexture::CubeMapFace>(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/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)) { } 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 <Qt3DRender/private/renderer_p.h> #include <Qt3DRender/private/managers_p.h> #include <QThreadPool> @@ -61,6 +62,7 @@ FrameGraphVisitor::FrameGraphVisitor(const FrameGraphManager *manager) QVector<FrameGraphNode *> 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<FrameGraphNode *> FrameGraphVisitor::traverse(FrameGraphNode *root) return m_leaves; } +// intended to be called after traverse +// (returns data that is captured during the traverse) +QVector<FrameGraphNode *> &&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<SubtreeEnabler*>(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<FrameGraphNode *> traverse(FrameGraphNode *root); + QVector<FrameGraphNode *> &&takeEnablersToDisable(); private: void visit(Render::FrameGraphNode *node); const FrameGraphManager *m_manager; QVector<FrameGraphNode *> m_leaves; + QVector<FrameGraphNode *> 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 <Qt3DRender/qsubtreeenabler.h> -#include <Qt3DRender/private/qframegraphnode_p.h> +#include "qsubtreeenabler_p.h" +#include <Qt3DRender/qframegraphnodecreatedchange.h> 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<QSubtreeEnablerData>::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 <private/qframegraphnode_p.h> + +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/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 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 <Qt3DRender/private/qsubtreeenabler_p.h> +#include <Qt3DCore/qpropertyupdatedchange.h> 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<const QSubtreeEnabler *>(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 <Qt3DRender/qsubtreeenabler.h> #include <Qt3DRender/private/framegraphnode_p.h> 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/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<Qt3DCore::QNodeId> 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<float> boundingVolumeData = data.value< QVector<float> >(); @@ -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/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 67bcb6c02..70ec70b2b 100644 --- a/src/render/frontend/qrenderaspect.cpp +++ b/src/render/frontend/qrenderaspect.cpp @@ -255,20 +255,20 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<Qt3DCore::QEntity, true>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers)); q->registerBackendType<Qt3DCore::QTransform, true>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer)); - q->registerBackendType<Qt3DRender::QCameraLens>(QSharedPointer<Render::CameraLensFunctor>::create(m_renderer, q)); - q->registerBackendType<QLayer>(QSharedPointer<Render::NodeFunctor<Render::Layer, Render::LayerManager> >::create(m_renderer)); - q->registerBackendType<QLevelOfDetail>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); - q->registerBackendType<QLevelOfDetailSwitch>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); - q->registerBackendType<QSceneLoader>(QSharedPointer<Render::RenderSceneFunctor>::create(m_renderer, m_nodeManagers->sceneManager())); - q->registerBackendType<QRenderTarget>(QSharedPointer<Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager> >::create(m_renderer)); - q->registerBackendType<QRenderTargetOutput>(QSharedPointer<Render::NodeFunctor<Render::RenderTargetOutput, Render::AttachmentManager> >::create(m_renderer)); - q->registerBackendType<QRenderSettings>(QSharedPointer<Render::RenderSettingsFunctor>::create(m_renderer)); - q->registerBackendType<QRenderState>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer)); + q->registerBackendType<Qt3DRender::QCameraLens, true>(QSharedPointer<Render::CameraLensFunctor>::create(m_renderer, q)); + q->registerBackendType<QLayer, true>(QSharedPointer<Render::NodeFunctor<Render::Layer, Render::LayerManager> >::create(m_renderer)); + q->registerBackendType<QLevelOfDetail, true>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); + q->registerBackendType<QLevelOfDetailSwitch, true>(QSharedPointer<Render::NodeFunctor<Render::LevelOfDetail, Render::LevelOfDetailManager> >::create(m_renderer)); + q->registerBackendType<QSceneLoader, true>(QSharedPointer<Render::RenderSceneFunctor>::create(m_renderer, m_nodeManagers->sceneManager())); + q->registerBackendType<QRenderTarget, true>(QSharedPointer<Render::NodeFunctor<Render::RenderTarget, Render::RenderTargetManager> >::create(m_renderer)); + q->registerBackendType<QRenderTargetOutput, true>(QSharedPointer<Render::NodeFunctor<Render::RenderTargetOutput, Render::AttachmentManager> >::create(m_renderer)); + q->registerBackendType<QRenderSettings, true>(QSharedPointer<Render::RenderSettingsFunctor>::create(m_renderer)); + q->registerBackendType<QRenderState, true>(QSharedPointer<Render::NodeFunctor<Render::RenderStateNode, Render::RenderStateManager> >::create(m_renderer)); // Geometry + Compute q->registerBackendType<QAttribute, true>(QSharedPointer<Render::NodeFunctor<Render::Attribute, Render::AttributeManager> >::create(m_renderer)); q->registerBackendType<QBuffer, true>(QSharedPointer<Render::BufferFunctor>::create(m_renderer, m_nodeManagers->bufferManager())); - q->registerBackendType<QComputeCommand>(QSharedPointer<Render::NodeFunctor<Render::ComputeCommand, Render::ComputeCommandManager> >::create(m_renderer)); + q->registerBackendType<QComputeCommand, true>(QSharedPointer<Render::NodeFunctor<Render::ComputeCommand, Render::ComputeCommandManager> >::create(m_renderer)); q->registerBackendType<QGeometry, true>(QSharedPointer<Render::NodeFunctor<Render::Geometry, Render::GeometryManager> >::create(m_renderer)); q->registerBackendType<QGeometryRenderer, true>(QSharedPointer<Render::GeometryRendererFunctor>::create(m_renderer, m_nodeManagers->geometryRendererManager())); q->registerBackendType<Qt3DCore::QArmature, true>(QSharedPointer<Render::NodeFunctor<Render::Armature, Render::ArmatureManager>>::create(m_renderer)); @@ -277,22 +277,22 @@ void QRenderAspectPrivate::registerBackendTypes() // Textures q->registerBackendType<QAbstractTexture, true>(QSharedPointer<Render::TextureFunctor>::create(m_renderer, m_nodeManagers->textureManager())); - q->registerBackendType<QAbstractTextureImage>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer, + q->registerBackendType<QAbstractTextureImage, true>(QSharedPointer<Render::TextureImageFunctor>::create(m_renderer, m_nodeManagers->textureImageManager())); // Material system q->registerBackendType<QEffect, true>(QSharedPointer<Render::NodeFunctor<Render::Effect, Render::EffectManager> >::create(m_renderer)); - q->registerBackendType<QFilterKey>(QSharedPointer<Render::NodeFunctor<Render::FilterKey, Render::FilterKeyManager> >::create(m_renderer)); + q->registerBackendType<QFilterKey, true>(QSharedPointer<Render::NodeFunctor<Render::FilterKey, Render::FilterKeyManager> >::create(m_renderer)); q->registerBackendType<QAbstractLight, true>(QSharedPointer<Render::RenderLightFunctor>::create(m_renderer, m_nodeManagers)); q->registerBackendType<QEnvironmentLight, true>(QSharedPointer<Render::NodeFunctor<Render::EnvironmentLight, Render::EnvironmentLightManager> >::create(m_renderer)); q->registerBackendType<QMaterial, true>(QSharedPointer<Render::NodeFunctor<Render::Material, Render::MaterialManager> >::create(m_renderer)); q->registerBackendType<QParameter, true>(QSharedPointer<Render::NodeFunctor<Render::Parameter, Render::ParameterManager> >::create(m_renderer)); q->registerBackendType<QRenderPass, true>(QSharedPointer<Render::NodeFunctor<Render::RenderPass, Render::RenderPassManager> >::create(m_renderer)); q->registerBackendType<QShaderData>(QSharedPointer<Render::RenderShaderDataFunctor>::create(m_renderer, m_nodeManagers)); - q->registerBackendType<QShaderProgram>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer)); - q->registerBackendType<QShaderProgramBuilder>(QSharedPointer<Render::NodeFunctor<Render::ShaderBuilder, Render::ShaderBuilderManager> >::create(m_renderer)); + q->registerBackendType<QShaderProgram, true>(QSharedPointer<Render::NodeFunctor<Render::Shader, Render::ShaderManager> >::create(m_renderer)); + q->registerBackendType<QShaderProgramBuilder, true>(QSharedPointer<Render::NodeFunctor<Render::ShaderBuilder, Render::ShaderBuilderManager> >::create(m_renderer)); q->registerBackendType<QTechnique, true>(QSharedPointer<Render::TechniqueFunctor>::create(m_renderer, m_nodeManagers)); - q->registerBackendType<QShaderImage>(QSharedPointer<Render::NodeFunctor<Render::ShaderImage, Render::ShaderImageManager>>::create(m_renderer)); + q->registerBackendType<QShaderImage, true>(QSharedPointer<Render::NodeFunctor<Render::ShaderImage, Render::ShaderImageManager>>::create(m_renderer)); // Framegraph q->registerBackendType<QFrameGraphNode, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::FrameGraphNode, QFrameGraphNode> >::create(m_renderer)); @@ -320,9 +320,9 @@ void QRenderAspectPrivate::registerBackendTypes() q->registerBackendType<QSubtreeEnabler, true>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::SubtreeEnabler, QSubtreeEnabler> >::create(m_renderer)); // Picking - q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer)); - q->registerBackendType<QRayCaster>(QSharedPointer<Render::NodeFunctor<Render::RayCaster, Render::RayCasterManager> >::create(m_renderer)); - q->registerBackendType<QScreenRayCaster>(QSharedPointer<Render::NodeFunctor<Render::RayCaster, Render::RayCasterManager> >::create(m_renderer)); + q->registerBackendType<QObjectPicker, true>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer)); + q->registerBackendType<QRayCaster, true>(QSharedPointer<Render::NodeFunctor<Render::RayCaster, Render::RayCasterManager> >::create(m_renderer)); + q->registerBackendType<QScreenRayCaster, true>(QSharedPointer<Render::NodeFunctor<Render::RayCaster, Render::RayCasterManager> >::create(m_renderer)); // Plugins for (const QString &plugin : qAsConst(m_pluginConfig)) 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); 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/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<Qt3DCore::QNodeCreatedChange<QSceneLoaderData>>(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<QPropertyUpdatedChange>(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<const QSceneLoader *>(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/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/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<Qt3DCore::QNodeCreatedChange<QFilterKeyData>>(change); - const auto &data = typedChange->data; - m_name = data.name; - m_value = data.value; -} + const QFilterKey *node = qobject_cast<const QFilterKey *>(frontEnd); + if (!node) + return; -void FilterKey::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case PropertyUpdated: { - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(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/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<Qt3DCore::QNodeCreatedChange<QShaderProgramData>>(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<const QShaderProgram *>(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<QShaderProgram::ShaderType>(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<QPropertyUpdatedChange>(); - 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<QString, ShaderUniform> 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<QByteArray> 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<QString> m_uniformsNames; QVector<int> m_uniformsNamesIds; QVector<ShaderUniform> m_uniforms; 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<QPropertyUpdatedChange>(); - QVariant propertyValue = propertyChange->value(); - - if (propertyChange->propertyName() == QByteArrayLiteral("shaderProgram")) - m_shaderProgramId = propertyValue.value<Qt3DCore::QNodeId>(); - 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<const QShaderProgramBuilder *>(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<Qt3DCore::QNodeCreatedChange<QShaderProgramBuilderData>>(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<ShaderType, QUrl (QShaderProgramBuilder::*)() const> 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/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 <Qt3DRender/private/qshaderimage_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DRender/qabstracttexture.h> 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<Qt3DCore::QPropertyUpdatedChange>(e); - if (e->type() == Qt3DCore::PropertyUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("texture")) { - m_textureId = propertyChange->value().value<Qt3DCore::QNodeId>(); - 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<QShaderImage::ImageFormat>(); - markDirty(AbstractRenderer::ParameterDirty); - } else if (propertyChange->propertyName() == QByteArrayLiteral("access")) { - m_access = propertyChange->value().value<QShaderImage::Access>(); - markDirty(AbstractRenderer::ParameterDirty); - } + const QShaderImage *node = qobject_cast<const QShaderImage *>(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<Qt3DCore::QNodeCreatedChange<QShaderImageData>>(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/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<Qt3DCore::QNodeCreatedChange<QObjectPickerData>>(change); - const auto &data = typedChange->data; - m_hoverEnabled = data.hoverEnabled; - m_dragEnabled = data.dragEnabled; - m_priority = data.priority; - notifyJob(); -} + const QObjectPicker *node = qobject_cast<const QObjectPicker *>(frontEnd); + if (!node) + return; -void ObjectPicker::notifyJob() -{ - if (m_renderer && m_renderer->pickBoundingVolumeJob()) - qSharedPointerCast<PickBoundingVolumeJob>(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<Qt3DCore::QPropertyUpdatedChange>(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<PickBoundingVolumeJob>(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/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 <Qt3DRender/private/abstractrenderer_p.h> #include <Qt3DRender/qabstractraycaster.h> +#include <Qt3DRender/qlayer.h> #include <Qt3DRender/private/qabstractraycaster_p.h> #include <Qt3DRender/private/raycastingjob_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> @@ -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<Qt3DCore::QNodeCreatedChange<QAbstractRayCasterData>>(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<const QAbstractRayCaster *>(frontEnd); + if (!node) + return; -void RayCaster::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - switch (e->type()) { - case PropertyValueAdded: { - const auto change = qSharedPointerCast<QPropertyNodeAddedChange>(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<QPropertyNodeRemovedChange>(e); - if (change->propertyName() == QByteArrayLiteral("layer")) { - m_layerIds.removeOne(change->removedNodeId()); - markDirty(AbstractRenderer::LayersDirty); - notifyJob(); - } - break; + const QAbstractRayCasterPrivate *d = static_cast<const QAbstractRayCasterPrivate *>(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<Qt3DCore::QPropertyUpdatedChange>(e); - - if (propertyChange->propertyName() == QByteArrayLiteral("origin")) { - m_origin = propertyChange->value().value<QVector3D>(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("direction")) { - m_direction = propertyChange->value().value<QVector3D>(); - } 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<QAbstractRayCaster::RunMode>(); - } else if (propertyChange->propertyName() == QByteArrayLiteral("filterMode")) { - m_filterMode = propertyChange->value().value<QAbstractRayCaster::FilterMode>(); - } + 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/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) 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<int> m_attributes; + QVector<int> 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 2df3d1270..45f13c424 100644 --- a/src/render/renderers/opengl/renderer/renderer.cpp +++ b/src/render/renderers/opengl/renderer/renderer.cpp @@ -92,6 +92,7 @@ #include <Qt3DRender/private/commandthread_p.h> #include <Qt3DRender/private/glcommands_p.h> #include <Qt3DRender/private/setfence_p.h> +#include <Qt3DRender/private/subtreeenabler_p.h> #include <Qt3DRender/qcameralens.h> #include <Qt3DCore/private/qeventfilterservice_p.h> @@ -197,6 +198,7 @@ Renderer::Renderer(QRenderAspect::RenderType type) , m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering)) , m_sendTextureChangesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendTextureChangesToFrontend(); }, JobTypes::SendTextureChangesToFrontend)) , m_sendSetFenceHandlesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendSetFenceHandlesToFrontend(); }, JobTypes::SendSetFenceHandlesToFrontend)) + , m_sendDisablesToFrontendJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { sendDisablesToFrontend(); }, JobTypes::SendDisablesToFrontend)) , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering)) , m_syncLoadingJobs(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncLoadingJobs)) , m_ownedContext(false) @@ -894,7 +896,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &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()); @@ -916,9 +918,8 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &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; @@ -939,7 +940,7 @@ void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &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; } @@ -1204,6 +1205,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<SubtreeEnabler *>(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 @@ -1808,26 +1824,32 @@ QVector<Qt3DCore::QAspectJobPtr> 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<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot()); - - // Remove leaf nodes that no longer exist from cache - const QList<FrameGraphNode *> 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<FrameGraphNode *> 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); builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); builder.setMaterialGathererCacheNeedsToBeRebuilt(materialCacheNeedsToBeRebuilt); - builder.setRenderableCacheNeedsToBeRebuilt(renderableDirty); - builder.setComputableCacheNeedsToBeRebuilt(computeableDirty); builder.setLightGathererCacheNeedsToBeRebuilt(lightsDirty); builder.prepareJobs(); @@ -2150,7 +2172,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<ShaderAttribute> shaderAttributes = shader->attributes(); @@ -2195,7 +2217,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/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h index bfab85e4f..c7b4f8805 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<std::function<void ()>> m_textureGathererJob; GenericLambdaJobPtr<std::function<void ()>> m_sendTextureChangesToFrontendJob; GenericLambdaJobPtr<std::function<void ()>> m_sendSetFenceHandlesToFrontendJob; + GenericLambdaJobPtr<std::function<void ()>> 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<HVao> m_abandonedVaos; @@ -402,6 +404,7 @@ private: QVector<HTexture> m_dirtyTextures; QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties; QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; + QVector<Qt3DCore::QNodeId> m_updatedDisables; Qt3DCore::QNodeIdVector m_textureIdsToCleanup; bool m_ownedContext; @@ -421,6 +424,8 @@ private: QMetaObject::Connection m_contextConnection; RendererCache m_cache; bool m_shouldSwapBuffers; + + QVector<FrameGraphNode *> m_frameGraphLeaves; }; } // namespace Render 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<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>(); const HMaterial materialHandle = entity->componentHandle<Material>(); const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId); - HGeometry geometryHandle = m_manager->lookupHandle<Geometry, GeometryManager, HGeometry>(geometryRenderer->geometryId()); - Geometry *geometry = m_manager->data<Geometry, GeometryManager>(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<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)), m_environmentLight); - // Store all necessary information for actual drawing if command is valid - command->m_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<Qt3DCore::QNodeId> 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 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 <class StateSetImpl, StateMask stateMask, typename ... T> 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); @@ -125,17 +125,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 { data.front.face = m_front->faceMode(); 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); @@ -128,17 +128,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 { data.front.face = m_front->faceMode(); 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<const QRenderStatePrivate *>(Qt3DCore::QNodePrivate::get(node)); + switch (d->m_type) { case AlphaCoverageStateMask: { return StateVariant::createState<AlphaCoverage>(); } case AlphaTestMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QAlphaTestData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<AlphaFunc>(data.alphaFunction, data.referenceValue); + const QAlphaTest *alphaTest = static_cast<const QAlphaTest *>(node); + return StateVariant::createState<AlphaFunc>(alphaTest->alphaFunction(), alphaTest->referenceValue()); } case BlendStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<BlendEquation>(data.blendFunction); + const QBlendEquation *blendEquation = static_cast<const QBlendEquation *>(node); + return StateVariant::createState<BlendEquation>(blendEquation->blendFunction()); } case BlendEquationArgumentsMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationArgumentsData>>(renderStateChange); - const auto &data = typedChange->data; + const QBlendEquationArguments *blendArgs = static_cast<const QBlendEquationArguments *>(node); return StateVariant::createState<BlendEquationArguments>( - 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<MSAAEnabled>(renderStateChange->isNodeEnabled()); + return StateVariant::createState<MSAAEnabled>(node->isEnabled()); } case CullFaceStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QCullFaceData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<CullFace>(data.mode); + const QCullFace *cullFace = static_cast<const QCullFace *>(node); + return StateVariant::createState<CullFace>(cullFace->mode()); } case DepthRangeMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QDepthRangeData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<DepthRange>(data.nearValue, data.farValue); + const QDepthRange *depthRange = static_cast<const QDepthRange *>(node); + return StateVariant::createState<DepthRange>(depthRange->nearValue(), depthRange->farValue()); } case DepthWriteStateMask: { - return StateVariant::createState<NoDepthMask>(false); + return StateVariant::createState<NoDepthMask>(!node->isEnabled()); } case DepthTestStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QDepthTestData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<DepthTest>(data.depthFunction); + const QDepthTest *depthTest = static_cast<const QDepthTest *>(node); + return StateVariant::createState<DepthTest>(depthTest->depthFunction()); } case RasterModeMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QRasterModeData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<RasterMode>(data.faceMode, data.rasterMode); + const QRasterMode *rasterMode = static_cast<const QRasterMode *>(node); + return StateVariant::createState<RasterMode>(rasterMode->faceMode(), rasterMode->rasterMode()); } case FrontFaceStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QFrontFaceData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<FrontFace>(data.direction); + const QFrontFace *frontFace = static_cast<const QFrontFace *>(node); + return StateVariant::createState<FrontFace>(frontFace->direction()); } case ScissorStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QScissorTestData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<ScissorTest>(data.left, data.bottom, - data.width, data.height); + const QScissorTest *scissorTest = static_cast<const QScissorTest *>(node); + return StateVariant::createState<ScissorTest>(scissorTest->left(), scissorTest->bottom(), + scissorTest->width(), scissorTest->height()); } case StencilTestStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilTestData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<StencilTest>(data.front.stencilFunction, - data.front.referenceValue, - data.front.comparisonMask, - data.back.stencilFunction, - data.back.referenceValue, - data.back.comparisonMask); + const QStencilTest *stencilTest = static_cast<const QStencilTest *>(node); + return StateVariant::createState<StencilTest>(stencilTest->front()->stencilFunction(), + stencilTest->front()->referenceValue(), + stencilTest->front()->comparisonMask(), + stencilTest->back()->stencilFunction(), + stencilTest->back()->referenceValue(), + stencilTest->back()->comparisonMask()); } case PointSizeMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPointSizeData>>(renderStateChange); - const auto &data = typedChange->data; - const bool isProgrammable = (data.sizeMode == QPointSize::Programmable); - return StateVariant::createState<PointSize>(isProgrammable, data.value); + const QPointSize *pointSize = static_cast<const QPointSize *>(node); + const bool isProgrammable = (pointSize->sizeMode() == QPointSize::Programmable); + return StateVariant::createState<PointSize>(isProgrammable, pointSize->value()); } case PolygonOffsetStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPolygonOffsetData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<PolygonOffset>(data.scaleFactor, data.depthSteps); + const QPolygonOffset *offset = static_cast<const QPolygonOffset *>(node); + return StateVariant::createState<PolygonOffset>(offset->scaleFactor(), offset->depthSteps()); } case ColorStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QColorMaskData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<ColorMask>(data.redMasked, data.greenMasked, - data.blueMasked, data.alphaMasked); + const QColorMask *colorMask = static_cast<const QColorMask *>(node); + return StateVariant::createState<ColorMask>(colorMask->isRedMasked(), colorMask->isGreenMasked(), + colorMask->isBlueMasked(), colorMask->isAlphaMasked()); } case ClipPlaneMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QClipPlaneData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<ClipPlane>(data.planeIndex, - data.normal, - data.distance); + const QClipPlane *clipPlane = static_cast<const QClipPlane *>(node); + return StateVariant::createState<ClipPlane>(clipPlane->planeIndex(), + clipPlane->normal(), + clipPlane->distance()); } case SeamlessCubemapMask: { @@ -209,21 +196,19 @@ StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChan } case StencilOpMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilOperationData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<StencilOp>(data.front.stencilTestFailureOperation, - data.front.depthTestFailureOperation, - data.front.allTestsPassOperation, - data.back.stencilTestFailureOperation, - data.back.depthTestFailureOperation, - data.back.allTestsPassOperation); + const QStencilOperation *stencilOp = static_cast<const QStencilOperation *>(node); + return StateVariant::createState<StencilOp>(stencilOp->front()->stencilTestFailureOperation(), + stencilOp->front()->depthTestFailureOperation(), + stencilOp->front()->allTestsPassOperation(), + stencilOp->back()->stencilTestFailureOperation(), + stencilOp->back()->depthTestFailureOperation(), + stencilOp->back()->allTestsPassOperation()); } case StencilWriteStateMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilMaskData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<StencilMask>(data.frontOutputMask, - data.backOutputMask); + const QStencilMask *stencilMask = static_cast<const QStencilMask *>(node); + return StateVariant::createState<StencilMask>(stencilMask->frontOutputMask(), + stencilMask->backOutputMask()); } case DitheringStateMask: { @@ -231,9 +216,8 @@ StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChan } case LineWidthMask: { - const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QLineWidthData>>(renderStateChange); - const auto &data = typedChange->data; - return StateVariant::createState<LineWidth>(data.value, data.smooth); + const QLineWidth *lineWidth = static_cast<const QLineWidth *>(node); + return StateVariant::createState<LineWidth>(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<Qt3DRender::QRenderStateCreatedChangeBase>(chang3); - m_impl = createStateImplementation(renderStateChange); -} + const QRenderState *node = qobject_cast<const QRenderState *>(frontEnd); + if (!node) + return; -void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - if (e->type() == Qt3DCore::PropertyUpdated) { - Qt3DCore::QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(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 <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/qstenciloperation_p.h> #include <Qt3DRender/private/qstenciltest_p.h> +#include <Qt3DRender/qblendequationarguments.h> +#include <Qt3DRender/qblendequation.h> +#include <Qt3DRender/qalphatest.h> +#include <Qt3DRender/qdepthrange.h> +#include <Qt3DRender/qdepthtest.h> +#include <Qt3DRender/qrastermode.h> +#include <Qt3DRender/qfrontface.h> +#include <Qt3DRender/qscissortest.h> +#include <Qt3DRender/qpolygonoffset.h> +#include <Qt3DRender/qcolormask.h> +#include <Qt3DRender/qclipplane.h> +#include <Qt3DRender/qstencilmask.h> +#include <Qt3DRender/qlinewidth.h> 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<const QBlendEquationArguments *>(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<const QBlendEquation *>(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<const QAlphaTest *>(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<const QDepthRange *>(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<const QDepthTest *>(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<const QRasterMode *>(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<const QCullFace *>(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<const QFrontFace *>(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<const QScissorTest *>(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<QStencilTestData>(); - 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<const QStencilTest *>(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<const QPointSize *>(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<const QPolygonOffset *>(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<const QColorMask *>(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<QVector3D>(); - else if (name == QByteArrayLiteral("distance")) std::get<2>(m_values) = value.toFloat(); + const QClipPlane *clipPlane = static_cast<const QClipPlane *>(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<QStencilOperationData>(); - 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<const QStencilOperation *>(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<const QStencilMask *>(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<const QLineWidth *>(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<BlendEquationArguments, BlendEquationArgumentsMask, GLenum, GLenum, GLenum, GLenum, bool, int> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT BlendEquation : public GenericState<BlendEquation, BlendStateMask, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState<AlphaFunc, AlphaTestMask, GLenum, GLclampf> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT MSAAEnabled : public GenericState<MSAAEnabled, MSAAEnabledStateMask, GLboolean> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT DepthRange : public GenericState<DepthRange, DepthRangeMask, double, double> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT DepthTest : public GenericState<DepthTest, DepthTestStateMask, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT RasterMode : public GenericState<RasterMode, RasterModeMask, GLenum, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT NoDepthMask : public GenericState<NoDepthMask, DepthWriteStateMask, GLboolean> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT CullFace : public GenericState<CullFace, CullFaceStateMask, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT FrontFace : public GenericState<FrontFace, FrontFaceStateMask, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT Dithering : public GenericState<Dithering, DitheringStateMask> @@ -126,13 +126,13 @@ class Q_AUTOTEST_EXPORT Dithering : public GenericState<Dithering, DitheringStat class Q_AUTOTEST_EXPORT ScissorTest : public GenericState<ScissorTest, ScissorStateMask, int, int, int, int> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT StencilTest : public GenericState<StencilTest, StencilTestStateMask, GLenum, int, uint, GLenum, int, uint> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, AlphaCoverageStateMask> @@ -142,26 +142,26 @@ class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, Alpha class Q_AUTOTEST_EXPORT PointSize : public GenericState<PointSize, PointSizeMask, bool, GLfloat> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState<PolygonOffset, PolygonOffsetStateMask, GLfloat, GLfloat> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT ColorMask : public GenericState<ColorMask, ColorStateMask, GLboolean, GLboolean, GLboolean, GLboolean> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT ClipPlane : public GenericState<ClipPlane, ClipPlaneMask, int, QVector3D, float> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState<SeamlessCubemap, SeamlessCubemapMask> @@ -171,19 +171,19 @@ class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState<SeamlessCubemap, S class Q_AUTOTEST_EXPORT StencilOp : public GenericState<StencilOp, StencilOpMask, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT StencilMask : public GenericState<StencilMask, StencilWriteStateMask, uint, uint> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; class Q_AUTOTEST_EXPORT LineWidth : public GenericState<LineWidth, LineWidthMask, GLfloat, bool> { public: - void updateProperty(const char *name, const QVariant &value) override; + void updateProperties(const QRenderState *node) override; }; } // namespace Render 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 <Qt3DCore/private/qnode_p.h> #include <Qt3DRender/private/qt3drender_global_p.h> #include <Qt3DRender/qabstracttexture.h> +#include <Qt3DRender/qtextureimagedatagenerator.h> 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/qtexture.cpp b/src/render/texture/qtexture.cpp index 5a6adece3..734942847 100644 --- a/src/render/texture/qtexture.cpp +++ b/src/render/texture/qtexture.cpp @@ -1156,6 +1156,7 @@ void TextureDownloadRequest::onCompleted() /*! \class Qt3DRender::QTexture1D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target1D target format. @@ -1176,6 +1177,7 @@ QTexture1D::~QTexture1D() /*! \class Qt3DRender::QTexture1DArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target1DArray target format. @@ -1196,6 +1198,7 @@ QTexture1DArray::~QTexture1DArray() /*! \class Qt3DRender::QTexture2D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2D target format. @@ -1216,6 +1219,7 @@ QTexture2D::~QTexture2D() /*! \class Qt3DRender::QTexture2DArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DArray target format. @@ -1236,6 +1240,7 @@ QTexture2DArray::~QTexture2DArray() /*! \class Qt3DRender::QTexture3D + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target3D target format. @@ -1256,6 +1261,7 @@ QTexture3D::~QTexture3D() /*! \class Qt3DRender::QTextureCubeMap + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetCubeMap target format. @@ -1276,6 +1282,7 @@ QTextureCubeMap::~QTextureCubeMap() /*! \class Qt3DRender::QTextureCubeMapArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetCubeMapArray target format. @@ -1296,6 +1303,7 @@ QTextureCubeMapArray::~QTextureCubeMapArray() /*! \class Qt3DRender::QTexture2DMultisample + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DMultisample target format. @@ -1316,6 +1324,7 @@ QTexture2DMultisample::~QTexture2DMultisample() /*! \class Qt3DRender::QTexture2DMultisampleArray + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a Target2DMultisampleArray target format. @@ -1336,6 +1345,7 @@ QTexture2DMultisampleArray::~QTexture2DMultisampleArray() /*! \class Qt3DRender::QTextureRectangle + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetRectangle target format. @@ -1356,6 +1366,7 @@ QTextureRectangle::~QTextureRectangle() /*! \class Qt3DRender::QTextureBuffer + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \since 5.5 \brief A QAbstractTexture with a TargetBuffer target format. @@ -1395,6 +1406,7 @@ void QTextureLoaderPrivate::updateGenerator() /*! \class Qt3DRender::QTextureLoader + \inheaderfile Qt3DRender/QTexture \inmodule Qt3DRender \brief Handles the texture loading and setting the texture's properties. */ @@ -1608,8 +1620,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: @@ -1636,6 +1649,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) { @@ -1648,7 +1669,7 @@ QSharedGLTexture::~QSharedGLTexture() } /*! - * \qmlproperty textureId + * \qmlproperty int SharedGLTexture::textureId * * The OpenGL texture id value that you want Qt3D to gain access to. */ 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<Qt3DCore::QNodeCreatedChange<QAbstractTextureImageData>>(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<const QAbstractTextureImage *>(frontEnd); + if (!node) + return; -void TextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) -{ - QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast<QPropertyUpdatedChange>(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<QAbstractTexture::CubeMapFace>(propertyChange->value().toInt()); - } else if (propertyChange->propertyName() == QByteArrayLiteral("dataGenerator")) { - m_generator = propertyChange->value().value<QTextureImageDataGeneratorPtr>(); - } + 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<const QAbstractTextureImagePrivate *>(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/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<Qt3DCore::QPropertyUpdatedChange>::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<Qt3DCore::QPropertyNodeAddedChange>(); - 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<Qt3DCore::QPropertyNodeRemovedChange>(); - 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(); } 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/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/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<int>(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<qreal> thresholds = {20.f, 30.f, 40.f}; - QVariant v; - v.setValue<decltype(thresholds)>(thresholds); + const QVector<qreal> 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.)); 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); 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<Qt3DCore::QPropertyUpdatedChange>(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value<int>(), 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<Qt3DCore::QPropertyUpdatedChange>(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value<int>(), 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<Qt3DCore::QPropertyUpdatedChange>(); - QCOMPARE(change->propertyName(), "frameCount"); - QCOMPARE(change->value().value<int>(), 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); 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<QSceneChange>()); + // 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<QPropertyUpdatedChange>(); - 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<QSceneChange>()); + backend1->syncFromFrontEnd(frontend1, false); // THEN QVERIFY(backend1->impl() == backend2->impl()); 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<Qt3DCore::QPropertyNodeAddedChange>(); - 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<Qt3DCore::QPropertyNodeRemovedChange>(); - 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/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); 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 <Qt3DRender/private/renderviewbuilder_p.h> #include <Qt3DRender/private/offscreensurfacehelper_p.h> #include <Qt3DRender/private/renderqueue_p.h> +#include <Qt3DRender/private/job_common_p.h> 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<Qt3DCore::QAspectJobPtr> 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(); @@ -298,23 +316,6 @@ private Q_SLOTS: 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(); 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; 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); } } 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<Qt3DCore::QPropertyUpdatedChange>::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()); 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<QByteArray>("property"); QTest::addColumn<Qt3DRender::QShaderProgram::ShaderType>("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); 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<Qt3DRender::Render::ShaderBuilder::ShaderType>(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<QByteArray>("property"); QTest::addColumn<Qt3DRender::Render::ShaderBuilder::ShaderType>("type"); QTest::addColumn<QUrl>("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(); 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 <Qt3DRender/private/qshaderimage_p.h> #include <Qt3DRender/private/shaderimage_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DRender/qtexture.h> #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); 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); 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<Qt3DRender::Render::Texture *>(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<Qt3DRender::Render::Texture *>(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<Qt3DRender::Render::Texture *>(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()); |