summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-10-30 15:30:52 +0100
committerPaul Lemire <paul.lemire@kdab.com>2018-11-14 06:16:56 +0000
commitf1b333c36a19cf85eab798fc1b1952ed063fedfe (patch)
treebed08fc0bd5d4a4e925d368786f3e8398e2ec908
parenta3761a118f07dd3d4bebc3b28fff01b5f91a0016 (diff)
QComputeCommand allow to control the run behavior
It can either be Continuous, like it was until now or Manual. When in manual mode, the compute shader will only be executed by calling trigger() Change-Id: Icaae24f4691ccd821297f967d564e7a883fa60b5 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/quick3d/imports/render/qt3dquick3drenderplugin.cpp1
-rw-r--r--src/render/backend/computecommand.cpp30
-rw-r--r--src/render/backend/computecommand_p.h8
-rw-r--r--src/render/frontend/qcomputecommand.cpp102
-rw-r--r--src/render/frontend/qcomputecommand.h13
-rw-r--r--src/render/frontend/qcomputecommand_p.h7
-rw-r--r--src/render/renderers/opengl/renderer/renderview.cpp5
-rw-r--r--tests/auto/render/computecommand/tst_computecommand.cpp75
-rw-r--r--tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp163
9 files changed, 396 insertions, 8 deletions
diff --git a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
index 98ac869c2..4c8e2c0ca 100644
--- a/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
+++ b/src/quick3d/imports/render/qt3dquick3drenderplugin.cpp
@@ -233,6 +233,7 @@ void Qt3DQuick3DRenderPlugin::registerTypes(const char *uri)
// Compute Job
qmlRegisterType<Qt3DRender::QComputeCommand>(uri, 2, 0, "ComputeCommand");
+ qmlRegisterType<Qt3DRender::QComputeCommand, 13>(uri, 2, 13, "ComputeCommand");
// Layers
qmlRegisterType<Qt3DRender::QLayer>(uri, 2, 0, "Layer");
diff --git a/src/render/backend/computecommand.cpp b/src/render/backend/computecommand.cpp
index 2b23df9aa..349941965 100644
--- a/src/render/backend/computecommand.cpp
+++ b/src/render/backend/computecommand.cpp
@@ -40,7 +40,6 @@
#include "computecommand_p.h"
#include <Qt3DCore/qnode.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
-#include <Qt3DRender/qcomputecommand.h>
#include <Qt3DRender/private/qcomputecommand_p.h>
#include <Qt3DRender/private/abstractrenderer_p.h>
@@ -51,7 +50,9 @@ namespace Qt3DRender {
namespace Render {
ComputeCommand::ComputeCommand()
- : BackendNode(ReadOnly)
+ : BackendNode(ReadWrite)
+ , m_frameCount(0)
+ , m_runType(QComputeCommand::Continuous)
{
m_workGroups[0] = 1;
m_workGroups[1] = 1;
@@ -68,6 +69,8 @@ void ComputeCommand::cleanup()
m_workGroups[0] = 1;
m_workGroups[1] = 1;
m_workGroups[2] = 1;
+ m_frameCount = 0;
+ m_runType = QComputeCommand::Continuous;
}
void ComputeCommand::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
@@ -77,6 +80,8 @@ void ComputeCommand::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePt
m_workGroups[0] = data.workGroupX;
m_workGroups[1] = data.workGroupY;
m_workGroups[2] = data.workGroupZ;
+ m_runType = data.runType;
+ m_frameCount = data.frameCount;
if (m_renderer != nullptr)
BackendNode::markDirty(AbstractRenderer::ComputeDirty);
}
@@ -91,11 +96,30 @@ void ComputeCommand::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
m_workGroups[1] = propertyChange->value().toInt();
else if (propertyChange->propertyName() == QByteArrayLiteral("workGroupZ"))
m_workGroups[2] = propertyChange->value().toInt();
- markDirty(AbstractRenderer::AllDirty);
+ 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());
+ markDirty(AbstractRenderer::ComputeDirty);
}
BackendNode::sceneChangeEvent(e);
}
+// Called from buildComputeRenderCommands in a job
+void ComputeCommand::updateFrameCount()
+{
+ // Disable frontend node when reaching 0
+ --m_frameCount;
+ if (m_frameCount <= 0) {
+ setEnabled(false);
+ auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
+ e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
+ e->setPropertyName("enabled");
+ e->setValue(false);
+ notifyObservers(e);
+ }
+}
+
} // Render
} // Qt3DRender
diff --git a/src/render/backend/computecommand_p.h b/src/render/backend/computecommand_p.h
index fb8ca39ff..10e10fd25 100644
--- a/src/render/backend/computecommand_p.h
+++ b/src/render/backend/computecommand_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DRender/private/backendnode_p.h>
+#include <Qt3DRender/qcomputecommand.h>
QT_BEGIN_NAMESPACE
@@ -73,10 +74,17 @@ public:
inline int x() const Q_DECL_NOTHROW { return m_workGroups[0]; }
inline int y() const Q_DECL_NOTHROW { return m_workGroups[1]; }
inline int z() const Q_DECL_NOTHROW { return m_workGroups[2]; }
+ inline int frameCount() const Q_DECL_NOTHROW { return m_frameCount; }
+ inline QComputeCommand::RunType runType() const Q_DECL_NOTHROW { return m_runType; }
+
+ // Called from a job
+ void updateFrameCount();
private:
void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override;
int m_workGroups[3];
+ int m_frameCount;
+ QComputeCommand::RunType m_runType;
};
} // Render
diff --git a/src/render/frontend/qcomputecommand.cpp b/src/render/frontend/qcomputecommand.cpp
index 5cb72a6ce..8b176cd4f 100644
--- a/src/render/frontend/qcomputecommand.cpp
+++ b/src/render/frontend/qcomputecommand.cpp
@@ -39,6 +39,7 @@
#include "qcomputecommand.h"
#include "qcomputecommand_p.h"
+#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -75,12 +76,14 @@ namespace Qt3DRender {
The compute shader is specified in the Material component of the same entity the
ComputeCommand is added to. The workGroupX, workGroupY and workGroupZ properties
specify the work group sizes for the compute shader invocation. DispatchCompute
- node needs to be present in the FrameGraph to actually issue the commands.
+ node needs to be present in the FrameGraph to actually issue the commands. The execution behavior
+ of the compute command can be controlled with the run type property.
- \note If the rendering policy is set to RenderSettings.OnDemand and there are no changes to the
- scene, the ComputeCommand will not be invoked repeatedly.
- The RenderSettings.Always render policy must be set for the ComputeCommand to be
- repeatedly invoked if there are no other changes to the scene that triggers rendering a new
+ \note If the rendering policy is set to RenderSettings.OnDemand, the run
+ type is set to Continuous and there are no changes to the scene, the
+ ComputeCommand will not be invoked repeatedly. The RenderSettings.Always
+ render policy must be set for the ComputeCommand to be repeatedly invoked
+ if there are no other changes to the scene that triggers rendering a new
frame.
*/
@@ -90,6 +93,19 @@ namespace Qt3DRender {
*/
/*!
+ \qmlproperty QComputeCommand::runType
+
+ Specifies whether the compute command should be performed every frame or
+ manually triggered.
+
+ \value Continuous Compute command is executed everyframe. This is the
+ default.
+
+ \value Manual CompouteCommand is executed for a given number of frames and
+ then the component disables itself.
+ */
+
+/*!
\qmlproperty int ComputeCommand::workGroupY
Specifies Y workgroup size.
*/
@@ -114,12 +130,36 @@ namespace Qt3DRender {
Specifies Z workgroup size.
*/
+/*!
+ \property QComputeCommand::runType
+
+ Specifies whether the compute command should be performed every frame or
+ manually triggered.
+
+ If set to Continuous, Compute command is executed everyframe. This is the
+ default.
+
+ If set to Manual CompouteCommand is executed for a given number of frames
+ and then the component disables itself.
+ */
+
QComputeCommandPrivate::QComputeCommandPrivate()
: Qt3DCore::QComponentPrivate()
, m_workGroupX(1)
, m_workGroupY(1)
, m_workGroupZ(1)
+ , m_runType(QComputeCommand::Continuous)
+ , m_frameCount(0)
+{
+}
+
+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);
}
/*!
@@ -154,6 +194,12 @@ int QComputeCommand::workGroupZ() const
return d->m_workGroupZ;
}
+QComputeCommand::RunType QComputeCommand::runType() const
+{
+ Q_D(const QComputeCommand);
+ return d->m_runType;
+}
+
/*!
Sets the workgroup for the first dimension to \a workGroupX.
*/
@@ -190,6 +236,50 @@ void QComputeCommand::setWorkGroupZ(int workGroupZ)
}
}
+void QComputeCommand::setRunType(QComputeCommand::RunType runType)
+{
+ Q_D(QComputeCommand);
+ if (d->m_runType != runType) {
+ d->m_runType = runType;
+ emit runTypeChanged();
+ }
+}
+
+/*!
+ When the run type is set to Manual, calling trigger will make the compute
+ command be executed for the next \a frameCount frames. Upon completion of
+ the execution, the enabled property will be set to false.
+ */
+void QComputeCommand::trigger(int frameCount)
+{
+ if (isEnabled())
+ qWarning() << Q_FUNC_INFO << "is triggered while it hasn't finished executing";
+
+ Q_D(QComputeCommand);
+ d->setFrameCount(frameCount);
+ setEnabled(true);
+}
+
+/*!
+ When the run type is set to Manual, calling trigger will make the compute
+ command be executed for the next \a frameCount frames. Upon completion of
+ the execution, the enabled property will be set to false. The size of the
+ workgroup previously set will be overridden with \a workGroupX, \a
+ workGroupY, \a workGroupZ.
+ */
+void QComputeCommand::trigger(int workGroupX, int workGroupY, int workGroupZ, int frameCount)
+{
+ if (isEnabled())
+ qWarning() << Q_FUNC_INFO << "is triggered while it hasn't finished executing";
+
+ setWorkGroupX(workGroupX);
+ setWorkGroupY(workGroupY);
+ setWorkGroupZ(workGroupZ);
+ Q_D(QComputeCommand);
+ d->setFrameCount(frameCount);
+ setEnabled(true);
+}
+
Qt3DCore::QNodeCreatedChangeBasePtr QComputeCommand::createNodeCreationChange() const
{
auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QComputeCommandData>::create(this);
@@ -198,6 +288,8 @@ Qt3DCore::QNodeCreatedChangeBasePtr QComputeCommand::createNodeCreationChange()
data.workGroupX = d->m_workGroupX;
data.workGroupY = d->m_workGroupY;
data.workGroupZ = d->m_workGroupZ;
+ data.runType = d->m_runType;
+ data.frameCount = d->m_frameCount;
return creationChange;
}
diff --git a/src/render/frontend/qcomputecommand.h b/src/render/frontend/qcomputecommand.h
index c31082197..ad7f89a4d 100644
--- a/src/render/frontend/qcomputecommand.h
+++ b/src/render/frontend/qcomputecommand.h
@@ -55,24 +55,37 @@ class QT3DRENDERSHARED_EXPORT QComputeCommand : public Qt3DCore::QComponent
Q_PROPERTY(int workGroupX READ workGroupX WRITE setWorkGroupX NOTIFY workGroupXChanged)
Q_PROPERTY(int workGroupY READ workGroupY WRITE setWorkGroupY NOTIFY workGroupYChanged)
Q_PROPERTY(int workGroupZ READ workGroupZ WRITE setWorkGroupZ NOTIFY workGroupZChanged)
+ Q_PROPERTY(RunType runType READ runType WRITE setRunType NOTIFY runTypeChanged REVISION 13)
public:
+ enum RunType {
+ Continuous = 0,
+ Manual
+ };
+ Q_ENUM(RunType)
+
explicit QComputeCommand(Qt3DCore::QNode *parent = nullptr);
~QComputeCommand();
int workGroupX() const;
int workGroupY() const;
int workGroupZ() const;
+ RunType runType() const;
public Q_SLOTS:
void setWorkGroupX(int workGroupX);
void setWorkGroupY(int workGroupY);
void setWorkGroupZ(int workGroupZ);
+ void setRunType(RunType runType);
+
+ void trigger(int frameCount = 1);
+ void trigger(int workGroupX, int workGroupY, int workGroupZ, int frameCount = 1);
Q_SIGNALS:
void workGroupXChanged();
void workGroupYChanged();
void workGroupZChanged();
+ void runTypeChanged();
private:
Q_DECLARE_PRIVATE(QComputeCommand)
diff --git a/src/render/frontend/qcomputecommand_p.h b/src/render/frontend/qcomputecommand_p.h
index 874edb1fc..fc3376d5b 100644
--- a/src/render/frontend/qcomputecommand_p.h
+++ b/src/render/frontend/qcomputecommand_p.h
@@ -52,6 +52,7 @@
//
#include <Qt3DCore/private/qcomponent_p.h>
+#include <Qt3DRender/qcomputecommand.h>
#include <Qt3DRender/private/qt3drender_global_p.h>
QT_BEGIN_NAMESPACE
@@ -66,6 +67,10 @@ public:
int m_workGroupX;
int m_workGroupY;
int m_workGroupZ;
+ QComputeCommand::RunType m_runType;
+ int m_frameCount;
+
+ void setFrameCount(int frameCount);
};
struct QComputeCommandData
@@ -73,6 +78,8 @@ struct QComputeCommandData
int workGroupX;
int workGroupY;
int workGroupZ;
+ QComputeCommand::RunType runType;
+ int frameCount;
};
} // Qt3DRender
diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp
index 66299e430..39fed2294 100644
--- a/src/render/renderers/opengl/renderer/renderview.cpp
+++ b/src/render/renderers/opengl/renderer/renderview.cpp
@@ -714,6 +714,11 @@ QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<En
if ((computeJob = entity->renderComponent<ComputeCommand>()) != nullptr
&& computeJob->isEnabled()) {
+ // Note: if frameCount has reached 0 in the previous frame, isEnabled
+ // would be false
+ if (computeJob->runType() == QComputeCommand::Manual)
+ computeJob->updateFrameCount();
+
const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>();
const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
diff --git a/tests/auto/render/computecommand/tst_computecommand.cpp b/tests/auto/render/computecommand/tst_computecommand.cpp
index 13688d299..1c8380f73 100644
--- a/tests/auto/render/computecommand/tst_computecommand.cpp
+++ b/tests/auto/render/computecommand/tst_computecommand.cpp
@@ -31,9 +31,11 @@
#include <Qt3DRender/qcomputecommand.h>
#include <Qt3DRender/private/qcomputecommand_p.h>
#include <Qt3DRender/private/computecommand_p.h>
+#include <Qt3DCore/private/qbackendnode_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include "qbackendnodetester.h"
#include "testrenderer.h"
+#include "testpostmanarbiter.h"
class tst_ComputeCommand : public Qt3DCore::QBackendNodeTester
{
@@ -52,6 +54,8 @@ private Q_SLOTS:
QCOMPARE(backendComputeCommand.x(), 1);
QCOMPARE(backendComputeCommand.y(), 1);
QCOMPARE(backendComputeCommand.z(), 1);
+ QCOMPARE(backendComputeCommand.runType(), Qt3DRender::QComputeCommand::Continuous);
+ QCOMPARE(backendComputeCommand.frameCount(), 0);
}
void checkCleanupState()
@@ -75,6 +79,8 @@ private Q_SLOTS:
computeCommand.setWorkGroupX(256);
computeCommand.setWorkGroupY(512);
computeCommand.setWorkGroupZ(128);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.trigger(6);
{
// WHEN
@@ -87,6 +93,8 @@ private Q_SLOTS:
QCOMPARE(backendComputeCommand.x(), computeCommand.workGroupX());
QCOMPARE(backendComputeCommand.y(), computeCommand.workGroupY());
QCOMPARE(backendComputeCommand.z(), computeCommand.workGroupZ());
+ QCOMPARE(backendComputeCommand.runType(), computeCommand.runType());
+ QCOMPARE(backendComputeCommand.frameCount(), 6);
}
{
// WHEN
@@ -151,8 +159,75 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.z(), newValue);
}
+ {
+ // 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);
+
+ // THEN
+ QCOMPARE(backendComputeCommand.runType(), newValue);
+ }
+ {
+ // WHEN
+ const int newValue = 32;
+ const auto change = Qt3DCore::QPropertyUpdatedChangePtr::create(Qt3DCore::QNodeId());
+ change->setPropertyName("frameCount");
+ change->setValue(newValue);
+ backendComputeCommand.sceneChangeEvent(change);
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), newValue);
+ }
}
+ void checkUpdateFrameCount()
+ {
+ // GIVEN
+ TestRenderer renderer;
+ TestArbiter arbiter;
+
+ Qt3DRender::QComputeCommand computeCommand;
+ Qt3DRender::Render::ComputeCommand backendComputeCommand;
+
+ computeCommand.setWorkGroupX(256);
+ computeCommand.setWorkGroupY(512);
+ computeCommand.setWorkGroupZ(128);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.trigger(6);
+
+
+ Qt3DCore::QBackendNodePrivate::get(&backendComputeCommand)->setArbiter(&arbiter);
+
+ backendComputeCommand.setRenderer(&renderer);
+ simulateInitialization(&computeCommand, &backendComputeCommand);
+
+ for (int i = 0; i < 5; ++i) {
+ // WHEN
+ backendComputeCommand.updateFrameCount();
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), 6 - (i + 1));
+ QCOMPARE(backendComputeCommand.isEnabled(), true);
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+
+ // WHEN
+ backendComputeCommand.updateFrameCount();
+
+ // THEN
+ QCOMPARE(backendComputeCommand.frameCount(), false);
+ QCOMPARE(backendComputeCommand.isEnabled(), false);
+ QCOMPARE(arbiter.events.size(), 1);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<int>(), false);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ }
};
QTEST_MAIN(tst_ComputeCommand)
diff --git a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
index 94609c129..cc07120a2 100644
--- a/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
+++ b/tests/auto/render/qcomputecommand/tst_qcomputecommand.cpp
@@ -52,6 +52,7 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupX(), 1);
QCOMPARE(computeCommand.workGroupY(), 1);
QCOMPARE(computeCommand.workGroupZ(), 1);
+ QCOMPARE(computeCommand.runType(), Qt3DRender::QComputeCommand::Continuous);
}
void checkPropertyChanges()
@@ -116,6 +117,25 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupZ(), newValue);
QCOMPARE(spy.count(), 0);
}
+ {
+ // WHEN
+ QSignalSpy spy(&computeCommand, SIGNAL(runTypeChanged()));
+ const Qt3DRender::QComputeCommand::RunType newValue = Qt3DRender::QComputeCommand::Manual;
+ computeCommand.setRunType(newValue);
+
+ // THEN
+ QVERIFY(spy.isValid());
+ QCOMPARE(computeCommand.runType(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ computeCommand.setRunType(newValue);
+
+ // THEN
+ QCOMPARE(computeCommand.runType(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
}
void checkCreationData()
@@ -126,6 +146,7 @@ private Q_SLOTS:
computeCommand.setWorkGroupX(128);
computeCommand.setWorkGroupY(512);
computeCommand.setWorkGroupZ(1024);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
// WHEN
QVector<Qt3DCore::QNodeCreatedChangeBasePtr> creationChanges;
@@ -145,6 +166,8 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupX(), cloneData.workGroupX);
QCOMPARE(computeCommand.workGroupY(), cloneData.workGroupY);
QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
+ QCOMPARE(computeCommand.runType(), cloneData.runType);
+ QCOMPARE(0, cloneData.frameCount);
QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
QCOMPARE(computeCommand.isEnabled(), true);
QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
@@ -171,6 +194,8 @@ private Q_SLOTS:
QCOMPARE(computeCommand.workGroupZ(), cloneData.workGroupZ);
QCOMPARE(computeCommand.id(), creationChangeData->subjectId());
QCOMPARE(computeCommand.isEnabled(), false);
+ QCOMPARE(computeCommand.runType(), cloneData.runType);
+ QCOMPARE(0, cloneData.frameCount);
QCOMPARE(computeCommand.isEnabled(), creationChangeData->isNodeEnabled());
QCOMPARE(computeCommand.metaObject(), creationChangeData->metaObject());
}
@@ -275,6 +300,144 @@ private Q_SLOTS:
}
+ void checkRunTypeUpdate()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+
+ {
+ // WHEN
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 1);
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "runType");
+ QCOMPARE(change->value().value<int>(), int(computeCommand.runType()));
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 0);
+ }
+ }
+
+ void checkTrigger()
+ {
+ // GIVEN
+ TestArbiter arbiter;
+ Qt3DRender::QComputeCommand computeCommand;
+ arbiter.setArbiterOnNode(&computeCommand);
+ computeCommand.setRunType(Qt3DRender::QComputeCommand::Manual);
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+
+ {
+ // WHEN
+ computeCommand.trigger(1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 2);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.trigger(2);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 2);
+ {
+ auto change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 2);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+
+ {
+ // WHEN
+ computeCommand.trigger(10, 11, 12, 1);
+ QCoreApplication::processEvents();
+
+ // THEN
+ QCOMPARE(arbiter.events.size(), 5);
+ {
+ auto change = arbiter.events.at(0).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupX");
+ QCOMPARE(change->value().value<int>(), 10);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(1).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupY");
+ QCOMPARE(change->value().value<int>(), 11);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(2).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "workGroupZ");
+ QCOMPARE(change->value().value<int>(), 12);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.at(3).staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "frameCount");
+ QCOMPARE(change->value().value<int>(), 1);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+ {
+ auto change = arbiter.events.last().staticCast<Qt3DCore::QPropertyUpdatedChange>();
+ QCOMPARE(change->propertyName(), "enabled");
+ QCOMPARE(change->value().value<bool>(), true);
+ QCOMPARE(change->type(), Qt3DCore::PropertyUpdated);
+ }
+
+ computeCommand.setEnabled(false);
+ QCoreApplication::processEvents();
+ arbiter.events.clear();
+ }
+ }
+
};
QTEST_MAIN(tst_QComputeCommand)