Commit f42bf69f authored by Qt Forward Merge Bot's avatar Qt Forward Merge Bot
Browse files

Merge remote-tracking branch 'origin/5.15' into dev

Change-Id: Iccba3193d6b7064f0cc04124e495dd36a2f19bcb
parents 08afa0d6 73bfd21f
......@@ -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();
......
......@@ -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) {
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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;
};
......
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 \
......
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
......@@ -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);
......
......@@ -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())));
......
......@@ -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;
......
......@@ -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)
{
......
......@@ -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;
};
......
......@@ -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) {