forked from qt-creator/qt-creator
QmlDesigner: fix shutdown crash via Q_GLOBAL_STATIC singleton
- Ensures proper lazy initialization and destruction order - Prevents null accesses during shutdown (triggered by missing null-checks in qtddeclarative QQuickShaderEffect) Change-Id: Ibcce41441b7472e483a3f36c27cf8acfbf45b0c8 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
// This file should match the BlurHelper.qml in qtquickdesigner repository, except for shader paths
|
// This file should match the BlurHelper.qml in qtquickdesigner repository, except for shader paths
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import EffectComposerPropertyData
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: rootItem
|
id: rootItem
|
||||||
@@ -20,8 +21,8 @@ Item {
|
|||||||
visible: false
|
visible: false
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
vertexShader: g_propertyData?.blur_vs_path ?? ""
|
vertexShader: GlobalPropertyData?.blur_vs_path ?? ""
|
||||||
fragmentShader: g_propertyData?.blur_fs_path ?? ""
|
fragmentShader: GlobalPropertyData?.blur_fs_path ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
@@ -7,6 +7,7 @@ import HelperWidgets as HelperWidgets
|
|||||||
import StudioControls as StudioControls
|
import StudioControls as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import EffectComposerBackend
|
import EffectComposerBackend
|
||||||
|
import EffectComposerPropertyData
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
@@ -298,8 +299,8 @@ Column {
|
|||||||
BlurHelper {
|
BlurHelper {
|
||||||
id: blurHelper
|
id: blurHelper
|
||||||
source: source
|
source: source
|
||||||
property int blurMax: g_propertyData?.blur_helper_max_level ?? 64
|
property int blurMax: GlobalPropertyData?.blur_helper_max_level ?? 64
|
||||||
property real blurMultiplier: g_propertyData?.blurMultiplier ?? 0
|
property real blurMultiplier: GlobalPropertyData?.blurMultiplier ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
@@ -210,7 +210,7 @@ void CompositionNode::parse(const QString &effectName, const QString &qenPath, c
|
|||||||
for (const QJsonValueConstRef &prop : jsonProps) {
|
for (const QJsonValueConstRef &prop : jsonProps) {
|
||||||
const auto uniform = new Uniform(effectName, prop.toObject(), qenPath);
|
const auto uniform = new Uniform(effectName, prop.toObject(), qenPath);
|
||||||
m_uniformsModel.addUniform(uniform);
|
m_uniformsModel.addUniform(uniform);
|
||||||
g_propertyData.insert(uniform->name(), uniform->value());
|
g_propertyData()->insert(uniform->name(), uniform->value());
|
||||||
if (uniform->type() == Uniform::Type::Define) {
|
if (uniform->type() == Uniform::Type::Define) {
|
||||||
// Changing defines requires rebaking the shaders
|
// Changing defines requires rebaking the shaders
|
||||||
connect(uniform, &Uniform::uniformValueChanged, this, &CompositionNode::rebakeRequested);
|
connect(uniform, &Uniform::uniformValueChanged, this, &CompositionNode::rebakeRequested);
|
||||||
@@ -335,7 +335,7 @@ void CompositionNode::openCodeEditor()
|
|||||||
void CompositionNode::addUniform(const QVariantMap &data)
|
void CompositionNode::addUniform(const QVariantMap &data)
|
||||||
{
|
{
|
||||||
const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {});
|
const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {});
|
||||||
g_propertyData.insert(uniform->name(), uniform->value());
|
g_propertyData()->insert(uniform->name(), uniform->value());
|
||||||
m_uniformsModel.addUniform(uniform);
|
m_uniformsModel.addUniform(uniform);
|
||||||
updateAreUniformsInUse(true);
|
updateAreUniformsInUse(true);
|
||||||
}
|
}
|
||||||
@@ -346,7 +346,7 @@ void CompositionNode::updateUniform(int index, const QVariantMap &data)
|
|||||||
|
|
||||||
const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {});
|
const auto uniform = new Uniform({}, QJsonObject::fromVariantMap(data), {});
|
||||||
|
|
||||||
g_propertyData.insert(uniform->name(), uniform->value());
|
g_propertyData()->insert(uniform->name(), uniform->value());
|
||||||
m_uniformsModel.updateUniform(index, uniform);
|
m_uniformsModel.updateUniform(index, uniform);
|
||||||
updateAreUniformsInUse(true);
|
updateAreUniformsInUse(true);
|
||||||
}
|
}
|
||||||
|
@@ -2547,8 +2547,8 @@ QString EffectComposerModel::getQmlComponentString(bool localFiles)
|
|||||||
s += l3 + "id: blurHelper\n";
|
s += l3 + "id: blurHelper\n";
|
||||||
s += l3 + "source: rootItem.source\n";
|
s += l3 + "source: rootItem.source\n";
|
||||||
int blurMax = 32;
|
int blurMax = 32;
|
||||||
if (g_propertyData.contains("BLUR_HELPER_MAX_LEVEL"))
|
if (g_propertyData()->contains("BLUR_HELPER_MAX_LEVEL"))
|
||||||
blurMax = g_propertyData["BLUR_HELPER_MAX_LEVEL"].toInt();
|
blurMax = g_propertyData()->value("BLUR_HELPER_MAX_LEVEL").toInt();
|
||||||
s += l3 + QString("property int blurMax: %1\n").arg(blurMax);
|
s += l3 + QString("property int blurMax: %1\n").arg(blurMax);
|
||||||
s += l3 + "property real blurMultiplier: rootItem.blurMultiplier\n";
|
s += l3 + "property real blurMultiplier: rootItem.blurMultiplier\n";
|
||||||
s += l2 + "}\n";
|
s += l2 + "}\n";
|
||||||
|
@@ -68,10 +68,10 @@ bool EffectComposerUniformsModel::setData(const QModelIndex &index, const QVaria
|
|||||||
updatedValue = QUrl::fromLocalFile(path).toString();
|
updatedValue = QUrl::fromLocalFile(path).toString();
|
||||||
|
|
||||||
uniform->setValue(updatedValue);
|
uniform->setValue(updatedValue);
|
||||||
g_propertyData.insert(uniform->name(), updatedValue);
|
g_propertyData()->insert(uniform->name(), updatedValue);
|
||||||
} else {
|
} else {
|
||||||
uniform->setValue(value);
|
uniform->setValue(value);
|
||||||
g_propertyData.insert(uniform->name(), value);
|
g_propertyData()->insert(uniform->name(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(index, index, {role});
|
emit dataChanged(index, index, {role});
|
||||||
|
@@ -100,11 +100,12 @@ EffectComposerWidget::EffectComposerWidget(EffectComposerView *view)
|
|||||||
|
|
||||||
QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(this, QmlDesigner::Constants::EVENT_EFFECTCOMPOSER_TIME);
|
QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(this, QmlDesigner::Constants::EVENT_EFFECTCOMPOSER_TIME);
|
||||||
|
|
||||||
m_quickWidget->rootContext()->setContextProperty("g_propertyData", &g_propertyData);
|
qmlRegisterSingletonInstance<QQmlPropertyMap>(
|
||||||
|
"EffectComposerPropertyData", 1, 0, "GlobalPropertyData", g_propertyData());
|
||||||
|
|
||||||
QString blurPath = "file:" + EffectUtils::nodesSourcesPath() + "/common/";
|
QString blurPath = "file:" + EffectUtils::nodesSourcesPath() + "/common/";
|
||||||
g_propertyData.insert(QString("blur_vs_path"), QString(blurPath + "bluritems.vert.qsb"));
|
g_propertyData()->insert("blur_vs_path", QString(blurPath + "bluritems.vert.qsb"));
|
||||||
g_propertyData.insert(QString("blur_fs_path"), QString(blurPath + "bluritems.frag.qsb"));
|
g_propertyData()->insert("blur_fs_path", QString(blurPath + "bluritems.frag.qsb"));
|
||||||
|
|
||||||
auto map = m_quickWidget->registerPropertyMap("EffectComposerBackend");
|
auto map = m_quickWidget->registerPropertyMap("EffectComposerBackend");
|
||||||
map->setProperties({{"effectComposerNodesModel", QVariant::fromValue(effectComposerNodesModel().data())},
|
map->setProperties({{"effectComposerNodesModel", QVariant::fromValue(effectComposerNodesModel().data())},
|
||||||
|
@@ -3,8 +3,14 @@
|
|||||||
|
|
||||||
#include "propertyhandler.h"
|
#include "propertyhandler.h"
|
||||||
|
|
||||||
|
#include <QQmlPropertyMap>
|
||||||
|
|
||||||
namespace EffectComposer {
|
namespace EffectComposer {
|
||||||
|
|
||||||
QQmlPropertyMap g_propertyData;
|
Q_GLOBAL_STATIC(QQmlPropertyMap, globalEffectComposerPropertyData)
|
||||||
|
|
||||||
|
QQmlPropertyMap *g_propertyData()
|
||||||
|
{
|
||||||
|
return globalEffectComposerPropertyData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,13 +3,16 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QQmlPropertyMap>
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QQmlPropertyMap;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace EffectComposer {
|
namespace EffectComposer {
|
||||||
|
|
||||||
// This will be used for binding dynamic properties
|
// This will be used for binding dynamic properties
|
||||||
// changes between C++ and QML.
|
// changes between C++ and QML.
|
||||||
extern QQmlPropertyMap g_propertyData;
|
QQmlPropertyMap *g_propertyData();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS
|
|||||||
m_enableMipmap = getBoolValue(propObj.value("enableMipmap"), false);
|
m_enableMipmap = getBoolValue(propObj.value("enableMipmap"), false);
|
||||||
// Update the mipmap property
|
// Update the mipmap property
|
||||||
QString mipmapProperty = mipmapPropertyName(m_name);
|
QString mipmapProperty = mipmapPropertyName(m_name);
|
||||||
g_propertyData[mipmapProperty] = m_enableMipmap;
|
g_propertyData()->insert(mipmapProperty, m_enableMipmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString controlType = propObj.value("controlType").toString();
|
QString controlType = propObj.value("controlType").toString();
|
||||||
|
Reference in New Issue
Block a user