diff options
author | Janne Kangas <janne.kangas@qt.io> | 2019-07-16 14:51:45 +0300 |
---|---|---|
committer | Janne Kangas <janne.kangas@qt.io> | 2019-08-09 13:46:54 +0300 |
commit | 2ac5dc0fcd1503fa11a90e17054f1d4ea370b6d6 (patch) | |
tree | 1beb0052a95c70ce5880966b1de8208b83ccb627 /src/api | |
parent | bb6fff1b707c15853f137b5a7b8797fa9415d33f (diff) |
Batch datainput value changes per-frame for QML context
Group all changes in datainput values on QML side together and send a
single per-frame command. This ameliorates the performance cost of frequent
value updates, especially for projects with large amount of datainputs.
Change-Id: Ib398f405dedb50ad3f5429f42024b3f490114dab
Task-id: QT3DS-3759
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/studio3d/q3dscommandqueue.cpp | 9 | ||||
-rw-r--r-- | src/api/studio3d/q3dscommandqueue_p.h | 1 | ||||
-rw-r--r-- | src/api/studio3d/q3dsdatainput.cpp | 7 | ||||
-rw-r--r-- | src/api/studio3d/q3dsdatainput_p.h | 3 | ||||
-rw-r--r-- | src/api/studio3d/q3dspresentation.cpp | 23 | ||||
-rw-r--r-- | src/api/studio3d/q3dspresentation_p.h | 3 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsrenderer.cpp | 13 | ||||
-rw-r--r-- | src/api/studio3dqml/q3dsstudio3d.cpp | 5 |
8 files changed, 61 insertions, 3 deletions
diff --git a/src/api/studio3d/q3dscommandqueue.cpp b/src/api/studio3d/q3dscommandqueue.cpp index e9eed29..102441b 100644 --- a/src/api/studio3d/q3dscommandqueue.cpp +++ b/src/api/studio3d/q3dscommandqueue.cpp @@ -240,6 +240,11 @@ void CommandQueue::copyCommands(CommandQueue &fromQueue) queueCommand(source.m_elementPath, source.m_commandType, source.m_stringValue, source.m_variantValue, source.m_intValues[0]); break; + case CommandType_SetDataInputBatch: + queueCommand(source.m_elementPath, source.m_commandType, source.m_stringValue, + source.m_data); + fromQueue.commandAt(i).m_data = nullptr; // This queue takes ownership of data + break; case CommandType_SetAttribute: queueCommand(source.m_elementPath, source.m_commandType, source.m_stringValue, source.m_variantValue); @@ -328,6 +333,10 @@ void CommandQueue::clear(bool deleteCommandData) delete static_cast<QHash<QString, Q3DSViewer::MeshData> *>(cmd.m_data); break; } + case CommandType_SetDataInputBatch: { + delete static_cast<QVector<QPair<QString, QVariant>> *>(cmd.m_data); + break; + } default: Q_ASSERT(false); // Should never come here break; diff --git a/src/api/studio3d/q3dscommandqueue_p.h b/src/api/studio3d/q3dscommandqueue_p.h index effb72e..a519ce7 100644 --- a/src/api/studio3d/q3dscommandqueue_p.h +++ b/src/api/studio3d/q3dscommandqueue_p.h @@ -68,6 +68,7 @@ enum CommandType { CommandType_KeyRelease, CommandType_SetGlobalAnimationTime, CommandType_SetDataInputValue, + CommandType_SetDataInputBatch, CommandType_CreateElements, CommandType_DeleteElements, CommandType_CreateMaterials, diff --git a/src/api/studio3d/q3dsdatainput.cpp b/src/api/studio3d/q3dsdatainput.cpp index 2a52963..bfd8b43 100644 --- a/src/api/studio3d/q3dsdatainput.cpp +++ b/src/api/studio3d/q3dsdatainput.cpp @@ -357,6 +357,11 @@ void Q3DSDataInputPrivate::setPresentation(Q3DSPresentation *presentation) m_presentation = presentation; } +void Q3DSDataInputPrivate::setDirty(bool dirty) +{ + m_dirty = dirty; +} + Q3DSDataInputPrivate::Q3DSDataInputPrivate(Q3DSDataInput *parent) : q_ptr(parent) { @@ -371,6 +376,8 @@ Q3DSDataInputPrivate::~Q3DSDataInputPrivate() void Q3DSDataInputPrivate::setValue(const QVariant &value, Q3DSDataInput::ValueRole valueRole) { m_value = value; + setDirty(true); + if (m_presentation) m_presentation->setDataInputValue(m_name, m_value, valueRole); } diff --git a/src/api/studio3d/q3dsdatainput_p.h b/src/api/studio3d/q3dsdatainput_p.h index 19b06f9..b5e0cc5 100644 --- a/src/api/studio3d/q3dsdatainput_p.h +++ b/src/api/studio3d/q3dsdatainput_p.h @@ -61,6 +61,7 @@ public: void setViewerApp(Q3DSViewer::Q3DSViewerApp *app); void setCommandQueue(CommandQueue *queue); void setPresentation(Q3DSPresentation *presentation); + void setDirty(bool dirty); protected: Q3DSDataInput *q_ptr; @@ -74,6 +75,8 @@ protected: float m_max = 0; float m_min = 0; + bool m_dirty = false; + // Note: Qt3d Runtime allows metadata to be both read and set, therefore requiring // internal representation of both keys and values to be QVariant as per API convention. // OpenGL Runtime, in contrast, only allows metadata to be read. As metadata now can only diff --git a/src/api/studio3d/q3dspresentation.cpp b/src/api/studio3d/q3dspresentation.cpp index cd9ecfa..3863fa3 100644 --- a/src/api/studio3d/q3dspresentation.cpp +++ b/src/api/studio3d/q3dspresentation.cpp @@ -848,12 +848,13 @@ void Q3DSPresentation::setGlobalAnimationTime(qint64 milliseconds) void Q3DSPresentation::setDataInputValue(const QString &name, const QVariant &value, Q3DSDataInput::ValueRole valueRole) { + // If we do not have viewerApp i.e. if this is a QML client context, do not send + // datainput set commands to the queue. They are batched and sent out at frameUpdate signal. if (d_ptr->m_viewerApp) { d_ptr->m_viewerApp->SetDataInputValue(name, value, (qt3ds::runtime::DataInputValueRole)valueRole); - } else if (d_ptr->m_commandQueue) { - d_ptr->m_commandQueue->queueCommand(QString(), CommandType_SetDataInputValue, - name, value, static_cast<int>(valueRole)); + } else { + d_ptr->m_dataInputsChanged = true; } } @@ -1512,6 +1513,7 @@ Q3DSPresentationPrivate::Q3DSPresentationPrivate(Q3DSPresentation *q) , m_commandQueue(nullptr) , m_streamProxy(nullptr) , m_delayedLoading(false) + , m_dataInputsChanged(false) { } @@ -1917,6 +1919,21 @@ bool Q3DSPresentationPrivate::isValidDataOutput(const Q3DSDataOutput *dataOutput return m_viewerApp->dataOutputs().contains(dataOutput->name()); } +void Q3DSPresentationPrivate::setDataInputValueBatch() +{ + // Allocated here, deleted after queue command has been processed. + QVector<QPair<QString, QVariant>> *theProperties = new QVector<QPair<QString, QVariant>>(); + for (const auto &di : qAsConst(m_dataInputs)) { + if (di->d_ptr->m_dirty) { + theProperties->append({di->name(), di->value()}); + di->d_ptr->m_dirty = false; + } + } + + if (!theProperties->empty() && m_commandQueue) + m_commandQueue->queueCommand({}, CommandType_SetDataInputBatch, {}, theProperties); +} + Q3DStudio::EKeyCode Q3DSPresentationPrivate::getScanCode(QKeyEvent *e) { enum { diff --git a/src/api/studio3d/q3dspresentation_p.h b/src/api/studio3d/q3dspresentation_p.h index 59b9f38..a68d0ee 100644 --- a/src/api/studio3d/q3dspresentation_p.h +++ b/src/api/studio3d/q3dspresentation_p.h @@ -90,6 +90,8 @@ public: QVector<Q3DSDataInput *> dataInputs(const QString &key) const; bool isValidDataOutput(const Q3DSDataOutput *dataOutput) const; + void setDataInputValueBatch(); + ViewerQmlStreamProxy *streamProxy(); Q3DStudio::EKeyCode getScanCode(QKeyEvent *e); @@ -118,6 +120,7 @@ private: QStringList m_createdElements; QStringList m_createdMaterials; QStringList m_createdMeshes; + bool m_dataInputsChanged; friend class Q3DSStudio3D; }; diff --git a/src/api/studio3dqml/q3dsrenderer.cpp b/src/api/studio3dqml/q3dsrenderer.cpp index 4d48a93..12f2e4d 100644 --- a/src/api/studio3dqml/q3dsrenderer.cpp +++ b/src/api/studio3dqml/q3dsrenderer.cpp @@ -370,6 +370,19 @@ void Q3DSRenderer::processCommands() cmd.m_stringValue, cmd.m_variantValue, static_cast<qt3ds::runtime::DataInputValueRole>(cmd.m_intValues[0])); break; + case CommandType_SetDataInputBatch: { + const QVector<QPair<QString, QVariant>> diValues + = *static_cast<QVector<QPair<QString, QVariant>> *>(cmd.m_data); + + for (const auto &di : diValues) { + m_runtime->SetDataInputValue(di.first, di.second, + qt3ds::runtime::DataInputValueRole::Value); + } + // No need for data after this, delete. + auto &command = m_commands.commandAt(i); + delete static_cast<QVector<QPair<QString, QVariant>> *>(command.m_data); + break; + } case CommandType_CreateElements: { m_runtime->createElements( cmd.m_elementPath, cmd.m_stringValue, diff --git a/src/api/studio3dqml/q3dsstudio3d.cpp b/src/api/studio3dqml/q3dsstudio3d.cpp index 38d32d4..8183d7b 100644 --- a/src/api/studio3dqml/q3dsstudio3d.cpp +++ b/src/api/studio3dqml/q3dsstudio3d.cpp @@ -454,6 +454,11 @@ void Q3DSStudio3D::tick() */ void Q3DSStudio3D::getCommands(bool emitInitialize, CommandQueue &renderQueue) { + if (m_presentation->d_ptr->m_dataInputsChanged) { + m_presentation->d_ptr->setDataInputValueBatch(); + m_presentation->d_ptr->m_dataInputsChanged = false; + } + if (emitInitialize) m_emitRunningChange = true; |