aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickshadereffect.cpp6
-rw-r--r--tests/auto/quick/qquickshadereffect/data/hideParent.qml133
-rw-r--r--tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp14
3 files changed, 152 insertions, 1 deletions
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index b3c8386fd9..8db4e7dc9e 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -868,7 +868,11 @@ void QQuickShaderEffect::itemChange(ItemChange change, const ItemChangeData &val
return;
}
#endif
- m_impl->handleItemChange(change, value);
+ // It's possible for itemChange to be called during destruction when deleting
+ // the QQuickShaderEffectImpl. We nullify m_impl before deleting it via another pointer
+ // to it, so we must check that it's not null before trying to use it here.
+ if (m_impl)
+ m_impl->handleItemChange(change, value);
QQuickItem::itemChange(change, value);
}
diff --git a/tests/auto/quick/qquickshadereffect/data/hideParent.qml b/tests/auto/quick/qquickshadereffect/data/hideParent.qml
new file mode 100644
index 0000000000..aeeb5b5f78
--- /dev/null
+++ b/tests/auto/quick/qquickshadereffect/data/hideParent.qml
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Item {
+ id: root
+ width: 640
+ height: 480
+ objectName: "qtbug86402Container"
+
+ property bool finished
+
+ Item {
+ id: popup
+ objectName: "popup"
+ width: 200
+ height: 200
+
+ Rectangle {
+ id: rect
+ objectName: "rect"
+ implicitWidth: 100
+ implicitHeight: 100
+ color: "blue"
+
+ Item {
+ id: ripple
+ objectName: "ripple"
+ anchors.fill: parent
+ visible: false
+
+ Rectangle {
+ id: rippleBox
+ objectName: "rippleBox"
+ property real cx
+ property real cy
+ x: cx - width / 2
+ y: cy - height / 2
+ width: 0
+ height: width
+ radius: width / 2
+ color: Qt.darker("red", 1.8)
+ }
+ layer.effect: ShaderEffect {
+ id: mask
+ objectName: "shaderEffect"
+ property variant source
+ property variant mask: rect
+
+ fragmentShader: "
+ uniform lowp sampler2D source;
+ uniform lowp sampler2D mask;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ gl_FragColor = texture2D(source, qt_TexCoord0) * texture2D(mask, qt_TexCoord0).a;
+ }"
+ }
+ }
+
+ SequentialAnimation {
+ id: rippleStartAnimation
+ running: popup.visible
+ onFinished: {
+ popup.parent = null
+ rippleEndAnimation.start()
+ }
+
+ ScriptAction {
+ script: {
+ rippleBox.width = 0
+ rippleBox.opacity = 0.3
+ ripple.visible = true
+ ripple.layer.enabled = true
+ }
+ }
+ NumberAnimation {
+ target: rippleBox
+ property: "width"
+ from: 0
+ to: Math.max(rect.width,
+ rect.height) * 2.2
+ duration: 100
+ }
+ }
+ SequentialAnimation {
+ id: rippleEndAnimation
+
+ onFinished: root.finished = true
+
+ //Causes Crash on QT Versions > 5.12.5
+ NumberAnimation {
+ target: rippleBox
+ property: "opacity"
+ to: 0
+ duration: 100
+ }
+ ScriptAction {
+ script: {
+ rippleBox.opacity = 0
+ ripple.layer.enabled = false
+ ripple.visible = false
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
index a57b7d4c1f..6537a64889 100644
--- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
+++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp
@@ -85,6 +85,8 @@ private slots:
void withoutQmlEngine();
+ void hideParent();
+
private:
enum PresenceFlags {
VertexPresent = 0x01,
@@ -336,6 +338,18 @@ void tst_qquickshadereffect::withoutQmlEngine()
delete window;
}
+// QTBUG-86402: hiding the parent of an item that uses an effect should not cause a crash.
+void tst_qquickshadereffect::hideParent()
+{
+ QScopedPointer<QQuickView> view(new QQuickView);
+ view->setSource(testFileUrl("hideParent.qml"));
+ QCOMPARE(view->status(), QQuickView::Ready);
+ view->show();
+ QVERIFY(QTest::qWaitForWindowExposed(view.data()));
+ // Should finish without crashing.
+ QTRY_VERIFY(view->rootObject()->property("finished").toBool());
+}
+
QTEST_MAIN(tst_qquickshadereffect)
#include "tst_qquickshadereffect.moc"