diff options
-rw-r--r-- | src/quick/items/qquickopenglshadereffect.cpp | 17 | ||||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp | 16 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index cad598d2c0..3aa00340b2 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -245,7 +245,11 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item, const QMetaObject *itemMetaObject, Key::ShaderType shaderType) { - QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(qmlEngine(item), item); + auto engine = qmlEngine(item); + if (!engine) + return; + + QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(engine, item); for (int i = 0; i < uniformData[shaderType].size(); ++i) { if (signalMappers[shaderType].at(i) == 0) continue; @@ -317,7 +321,8 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, Key::ShaderType shaderType, const QByteArray &code) { - QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(qmlEngine(item), item); + auto engine = qmlEngine(item); + QQmlPropertyCache *propCache = (engine) ? QQmlData::ensurePropertyCache(engine, item) : nullptr; int index = 0; int typeIndex = -1; int typeLength = 0; @@ -350,9 +355,11 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item, } else if (nameLength > srLen && qstrncmp("qt_SubRect_", s + nameIndex, srLen) == 0) { d.specialType = UniformData::SubRect; } else { - if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) { - if (!pd->isFunction()) - d.propertyIndex = pd->coreIndex(); + if (propCache) { + if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) { + if (!pd->isFunction()) + d.propertyIndex = pd->coreIndex(); + } } const int mappedId = uniformData[shaderType].size() | (shaderType << 16); mapper = new QtPrivate::MappedSlotObject([this, mappedId](){ diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp index f601f520bb..a57b7d4c1f 100644 --- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp +++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp @@ -46,6 +46,10 @@ class TestShaderEffect : public QQuickShaderEffect Q_PROPERTY(QMatrix4x4 mat4x4 READ mat4x4Read NOTIFY dummyChanged) public: + TestShaderEffect(QQuickItem* parent = nullptr) : QQuickShaderEffect(parent) + { + } + QMatrix4x4 mat4x4Read() const { return QMatrix4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1); } QVariant dummyRead() const { return QVariant(); } @@ -79,6 +83,8 @@ private slots: void deleteShaderEffectSource(); void twoImagesOneShaderEffect(); + void withoutQmlEngine(); + private: enum PresenceFlags { VertexPresent = 0x01, @@ -320,6 +326,16 @@ void tst_qquickshadereffect::twoImagesOneShaderEffect() delete view; } +void tst_qquickshadereffect::withoutQmlEngine() +{ + // using a shader without QML engine used to crash + auto window = new QQuickWindow; + auto shaderEffect = new TestShaderEffect(window->contentItem()); + shaderEffect->setVertexShader(""); + QVERIFY(shaderEffect->isComponentComplete()); + delete window; +} + QTEST_MAIN(tst_qquickshadereffect) #include "tst_qquickshadereffect.moc" |