diff options
author | Michael Brasser <mbrasser@ford.com> | 2019-08-28 11:01:40 -0500 |
---|---|---|
committer | Michael Brasser <mbrasser@ford.com> | 2019-09-24 08:38:45 -0500 |
commit | 3ad357371468c0da04b2964f040da41506379178 (patch) | |
tree | 5f573c5df5f74b1ec275791b2a356d96bfdeae59 /src/render/framegraph | |
parent | a364f08e6026eaebfdf6d0edf08d433c8814da84 (diff) |
Support transient enablement in QSubtreeEnabler
Change-Id: I422cf0fb0991319b0f54e5a26b9b3694cb093454
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/framegraph')
-rw-r--r-- | src/render/framegraph/framegraph.pri | 1 | ||||
-rw-r--r-- | src/render/framegraph/framegraphvisitor.cpp | 19 | ||||
-rw-r--r-- | src/render/framegraph/framegraphvisitor_p.h | 2 | ||||
-rw-r--r-- | src/render/framegraph/qsubtreeenabler.cpp | 78 | ||||
-rw-r--r-- | src/render/framegraph/qsubtreeenabler.h | 21 | ||||
-rw-r--r-- | src/render/framegraph/qsubtreeenabler_p.h | 80 | ||||
-rw-r--r-- | src/render/framegraph/subtreeenabler.cpp | 37 | ||||
-rw-r--r-- | src/render/framegraph/subtreeenabler_p.h | 8 |
8 files changed, 240 insertions, 6 deletions
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/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 |