diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2020-10-14 11:06:01 +0200 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2020-10-15 11:12:49 +0200 |
commit | 266cd7638d887b31d56964a0f13fe208821703b1 (patch) | |
tree | 8d88f95fdc1a70ac6b899af012c617ea83dd1df8 /tests | |
parent | 678d4ec4b68d43d0c748a8ec62a13716f83a27cf (diff) |
QQuickShaderEffect: fix crash when hiding parent
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.
Pick-to: 5.15
Fixes: QTBUG-86402
Change-Id: If4955445f7cc0d1f376bc9b86b95e1cca4d88ede
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/qquickshadereffect/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/data/hideParent.qml | 127 | ||||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/data/opacity-mask.frag | 19 | ||||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/data/opacity-mask.frag.qsb | bin | 0 -> 1411 bytes | |||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/resources.qrc | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp | 14 |
6 files changed, 164 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickshadereffect/CMakeLists.txt b/tests/auto/quick/qquickshadereffect/CMakeLists.txt index 92a1baa227..6eebadeedf 100644 --- a/tests/auto/quick/qquickshadereffect/CMakeLists.txt +++ b/tests/auto/quick/qquickshadereffect/CMakeLists.txt @@ -27,6 +27,8 @@ set(resources_resource_files "data/connections.qml" "data/deleteShaderEffectSource.qml" "data/deleteSourceItem.qml" + "data/hideParent.qml" + "data/opacity-mask.frag.qsb" "data/red.frag" "data/star.png" "data/test.frag" diff --git a/tests/auto/quick/qquickshadereffect/data/hideParent.qml b/tests/auto/quick/qquickshadereffect/data/hideParent.qml new file mode 100644 index 0000000000..e862dfaa01 --- /dev/null +++ b/tests/auto/quick/qquickshadereffect/data/hideParent.qml @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** 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 maskSource: rect + + fragmentShader: "opacity-mask.frag.qsb" + } + } + + 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/data/opacity-mask.frag b/tests/auto/quick/qquickshadereffect/data/opacity-mask.frag new file mode 100644 index 0000000000..94a80b8a99 --- /dev/null +++ b/tests/auto/quick/qquickshadereffect/data/opacity-mask.frag @@ -0,0 +1,19 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + // qt_Matrix and qt_Opacity must always be both present + // if the built-in vertex shader is used. + mat4 qt_Matrix; + float qt_Opacity; +}; + +layout(binding = 1) uniform sampler2D source; +layout(binding = 2) uniform sampler2D maskSource; + +void main() +{ + fragColor = texture(source, qt_TexCoord0.st) * (texture(maskSource, qt_TexCoord0.st).a) * qt_Opacity; +} diff --git a/tests/auto/quick/qquickshadereffect/data/opacity-mask.frag.qsb b/tests/auto/quick/qquickshadereffect/data/opacity-mask.frag.qsb Binary files differnew file mode 100644 index 0000000000..29ce0b21a0 --- /dev/null +++ b/tests/auto/quick/qquickshadereffect/data/opacity-mask.frag.qsb diff --git a/tests/auto/quick/qquickshadereffect/resources.qrc b/tests/auto/quick/qquickshadereffect/resources.qrc index 2789a6eecb..50c4c82036 100644 --- a/tests/auto/quick/qquickshadereffect/resources.qrc +++ b/tests/auto/quick/qquickshadereffect/resources.qrc @@ -12,5 +12,7 @@ <file>data/+qsb/test.vert</file> <file>data/+qsb/test.frag</file> <file>data/+qsb/red.frag</file> + <file>data/hideParent.qml</file> + <file>data/opacity-mask.frag.qsb</file> </qresource> </RCC> diff --git a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp index 9bc4b20968..fa5a0ed384 100644 --- a/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp +++ b/tests/auto/quick/qquickshadereffect/tst_qquickshadereffect.cpp @@ -82,6 +82,8 @@ private slots: void withoutQmlEngine(); + void hideParent(); + private: enum PresenceFlags { VertexPresent = 0x01, @@ -177,6 +179,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(QUrl(QStringLiteral("qrc:/data/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" |