summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2022-06-13 14:51:27 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2022-06-16 13:53:43 +0000
commit9c3636af497f8bdb2745bf85cc0286c9c6675987 (patch)
tree7c429f23a29451c7302eaac21efe9e36a7a380fd
parent50aadacb6e670597fc308d409bcdae96e7efa9c0 (diff)
downloadqt-creator-9c3636af497f8bdb2745bf85cc0286c9c6675987.tar.gz
QmlDesigner: Ensure materials render properly after puppet reset
This is a workaround for quick3d issue QTBUG-103316, where material library materials for editor are properly initialized only if the first encountered View3D in the scene is also rendered first. Fixes: QDS-7084 Change-Id: I8bb6a8e6bfe2fcffddfe86f92157d386fdf4095d Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp42
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h1
2 files changed, 42 insertions, 1 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index d614901ca9..97a60b5405 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -848,6 +848,18 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D(bool timerC
m_activeSceneIdUpdateTimer.stop();
}
+ // We may have to substitute another scene to work around QTBUG-103316
+ // The worked around issue is that if a material is used in multiple scenes, there is some
+ // kind of ownership for it in the first View3D that uses it, so if that view is not rendered
+ // first, the material will not be properly initialized for other views using it.
+ // To make materials work properly, we ensure that views are rendered at least once in the
+ // order they appear in the scene.
+ if (!m_priorityView3DsToRender.isEmpty()) {
+ QObject *sceneRoot = find3DSceneRoot(m_priorityView3DsToRender.first());
+ if (sceneRoot)
+ activeSceneVar = objectToVariant(sceneRoot);
+ }
+
QMetaObject::invokeMethod(m_editView3DData.rootItem, "setActiveScene", Qt::QueuedConnection,
Q_ARG(QVariant, activeSceneVar),
Q_ARG(QVariant, QVariant::fromValue(sceneId)));
@@ -1010,7 +1022,7 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
// If we have only one or no render queued, send the result to the creator side.
// Otherwise, we'll hold on that until we have rendered all pending frames to ensure sent
// results are correct.
- if (m_need3DEditViewRender <= 1) {
+ if (m_priorityView3DsToRender.isEmpty() && m_need3DEditViewRender <= 1) {
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::Render3DView,
QVariant::fromValue(imgContainer)});
#ifdef QUICK3D_PARTICLES_MODULE
@@ -1021,6 +1033,25 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
#endif
}
+ if (!m_priorityView3DsToRender.isEmpty()) {
+ static int tryCounter = 0;
+ QObject *sceneRoot = find3DSceneRoot(m_priorityView3DsToRender.first());
+ bool needAnotherRender = false;
+ if (sceneRoot) {
+ // Active scene is updated asynchronously, so verify we are actually rendering
+ // the correct priority scene
+ QObject *activeScene = QQmlProperty::read(m_editView3DData.rootItem, "activeScene").value<QObject *>();
+ needAnotherRender = activeScene != sceneRoot;
+ }
+
+ if (!needAnotherRender || ++tryCounter > 10) {
+ m_priorityView3DsToRender.removeFirst();
+ updateActiveSceneToEditView3D();
+ tryCounter = 0;
+ }
+ ++m_need3DEditViewRender;
+ }
+
if (m_need3DEditViewRender > 0) {
// We queue another render even if the requested render count was one, because another
// render is needed to ensure gizmo geometries are properly updated.
@@ -1057,6 +1088,13 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
{
// This crashes on Qt 6.0.x due to QtQuick3D issue, so the preview generation is disabled
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) || QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
+ if (!m_priorityView3DsToRender.isEmpty()) {
+ // Postpone any preview renders until we have rendered the priority views to ensure
+ // materials in material library are properly initialized
+ m_renderModelNodeImageViewTimer.start(17);
+ return;
+ }
+
RequestModelNodePreviewImageCommand cmd = *m_modelNodePreviewImageCommands.begin();
ServerNodeInstance instance;
if (cmd.renderItemId() >= 0)
@@ -1574,6 +1612,8 @@ void Qt5InformationNodeInstanceServer::add3DViewPorts(const QList<ServerNodeInst
for (const ServerNodeInstance &instance : instanceList) {
if (instance.isSubclassOf("QQuick3DViewport")) {
QObject *obj = instance.internalObject();
+ if (!m_editView3DSetupDone)
+ m_priorityView3DsToRender.append(obj); // Workaround for quick3d bug QTBUG-103316
if (!m_view3Ds.contains(obj)) {
m_view3Ds << obj;
QObject::connect(obj, SIGNAL(widthChanged()), this, SLOT(handleView3DSizeChange()));
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
index 9f6e450690..c85a2730c4 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h
@@ -165,6 +165,7 @@ private:
QSet<QObject *> m_view3Ds;
QMultiHash<QObject *, QObject *> m_3DSceneMap; // key: scene root, value: node
QObject *m_active3DView = nullptr;
+ QList<QObject *> m_priorityView3DsToRender;
QObject *m_active3DScene = nullptr;
QSet<ServerNodeInstance> m_parentChangedSet;
QList<ServerNodeInstance> m_completedComponentList;