aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2015-01-26 15:53:15 +0100
committerMitch Curtis <mitch.curtis@digia.com>2015-01-26 17:28:37 +0100
commit93affd9ff660456bde2d380788ea8ebfabb0f1c3 (patch)
tree70482566d189e3627404145998be97205c11f467
parent15ffff51b5cc92eb875785bbd16b6385638fe5dd (diff)
Canvas: don't crash when getContext("2d") is called on destruction.
We'd assume that a Window existed when that's not always the case. For example: import QtQuick 2.4 import QtQuick.Window 2.2 Window { Loader { sourceComponent: Canvas { Component.onDestruction: getContext("2d") } Component.onCompleted: active = false } } Change-Id: I5f30876e21ced5658adfa3bac494fd4196e0a7e3 Task-number: QTBUG-42222 Reviewed-by: Ulf Hermann <ulf.hermann@theqtcompany.com>
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp3
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml5
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml46
3 files changed, 54 insertions, 0 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index c31b7726c4..4b28517701 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -1124,6 +1124,9 @@ bool QQuickCanvasItem::createContext(const QString &contextType)
{
Q_D(QQuickCanvasItem);
+ if (!window())
+ return false;
+
if (contextType == QLatin1String("2d")) {
if (d->contextType.compare(QLatin1String("2d"), Qt::CaseInsensitive) != 0) {
d->contextType = QLatin1String("2d");
diff --git a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
index b0cae69fe3..e49f0ac462 100644
--- a/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/CanvasTestCase.qml
@@ -25,6 +25,11 @@ TestCase {
return [];
}
+ function renderStrategyToString(renderStrategy) {
+ return renderStrategy === Canvas.Immediate ? "Canvas.Immediate" :
+ (renderStrategy === Canvas.Threaded ? "Canvas.Threaded" : "Canvas.Cooperative");
+ }
+
function createCanvasObject(data) {
return component.createObject(testCase, data.properties);
}
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
index 31413c23cd..79c89bb2fc 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
@@ -595,5 +595,51 @@ CanvasTestCase {
canvas.destroy();
}
+
+ function test_getContextOnDestruction_data() {
+ // We want to test all possible combinations deemed valid by the testcase,
+ // but we can't test FramebufferObject due to difficulties ignoring the "available" warning.
+ var allData = testData("2d");
+ var ourData = [];
+
+ for (var i = 0; i < allData.length; ++i) {
+ if (allData[i].properties.renderTarget !== Canvas.FramebufferObject) {
+ var row = allData[i].properties;
+ row.tag = allData[i].tag;
+ ourData.push(row);
+ }
+ }
+
+ return ourData;
+ }
+
+ function test_getContextOnDestruction(data) {
+ try {
+ var canvasWindow = Qt.createQmlObject("
+ import QtQuick 2.4\n
+ import QtQuick.Window 2.2\n
+ Window {\n
+ function test() {\n
+ loader.active = true\n
+ loader.active = false\n
+ }\n
+ Loader {\n
+ id: loader\n
+ active: false\n
+ sourceComponent: Canvas {\n
+ renderStrategy: " + renderStrategyToString(data.renderStrategy) + "\n
+ Component.onDestruction: getContext(\"2d\")
+ }\n
+ }\n
+ }\n",
+ testCase);
+ verify(canvasWindow);
+ canvasWindow.test();
+ // Shouldn't crash when destruction is done.
+ wait(0);
+ } catch (exception) {
+ fail(exception.message);
+ }
+ }
}