diff options
author | Jesus Fernandez <jesus.fernandez@qt.io> | 2018-08-30 20:33:46 +0200 |
---|---|---|
committer | Jesus Fernandez <Jesus.Fernandez@qt.io> | 2018-09-13 14:08:38 +0000 |
commit | dadeb1bcb2bcbbf347a711a88b9e59d45c523df3 (patch) | |
tree | 2676b9f2a7e8eeb90423b01cdd11188292c4b4a2 | |
parent | b6fcf62d482215f0d5c0fa443cd4ae470f2548cf (diff) |
Add reload and update tests
This patch also copies part of the code of an example form
qtdeclarative that reproduces an update bug.
Change-Id: I4b9c2be89d4110d36a04c46bb0865c82b3a2cd16
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r-- | tests/plugins/platforms/webgl/LauncherList.qml | 252 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/SimpleLauncherDelegate.qml | 138 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/colors.qml | 49 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/images/back.png | bin | 0 -> 1590 bytes | |||
-rw-r--r-- | tests/plugins/platforms/webgl/images/next.png | bin | 0 -> 1371 bytes | |||
-rw-r--r-- | tests/plugins/platforms/webgl/launcher.qml | 65 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/parameters.h | 8 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/tst_webgl.cpp | 267 | ||||
-rw-r--r-- | tests/plugins/platforms/webgl/webgl.pro | 8 |
9 files changed, 764 insertions, 23 deletions
diff --git a/tests/plugins/platforms/webgl/LauncherList.qml b/tests/plugins/platforms/webgl/LauncherList.qml new file mode 100644 index 0000000..e532b53 --- /dev/null +++ b/tests/plugins/platforms/webgl/LauncherList.qml @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Crimson AS <info@crimson.no> +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + property int activePageCount: 0 + + //model is a list of {"name":"somename", "url":"file:///some/url/mainfile.qml"} + //function used to add to model A) to enforce scheme B) to allow Qt.resolveUrl in url assignments + + color: "#eee" + function addExample(name, desc, url) { + myModel.append({"name":name, "description":desc, "url":url}) + } + function showExample(url) { + pageComponent.createObject(pageContainer, { exampleUrl: url }).show() + } + + // The container rectangle here is used to give a nice "feel" when + // transitioning into an example. + Rectangle { + anchors.fill: parent + color: "black" + + ListView { + id: launcherList + clip: true + delegate: SimpleLauncherDelegate{ + onClicked: showExample(url) + } + model: ListModel {id:myModel} + anchors.fill: parent + enabled: opacity == 1.0 + } + } + + Item { + id: pageContainer + anchors.fill: parent + } + + Component { + id: pageComponent + Rectangle { + id: page + clip: true + property url exampleUrl + width: parent.width + height: parent.height - bar.height + color: "white" + MouseArea{ + //Eats mouse events + anchors.fill: parent + } + Loader{ + focus: true + source: parent.exampleUrl + anchors.fill: parent + } + + x: -width + + function show() { + showAnim.start() + } + + function exit() { + exitAnim.start() + } + + ParallelAnimation { + id: showAnim + ScriptAction { + script: activePageCount++ + } + NumberAnimation { + target: launcherList + property: "opacity" + from: 1.0 + to: 0.0 + duration: 500 + } + NumberAnimation { + target: launcherList + property: "scale" + from: 1.0 + to: 0.0 + duration: 500 + } + NumberAnimation { + target: page + property: "x" + from: -page.width + to: 0 + duration: 300 + } + } + SequentialAnimation { + id: exitAnim + + ScriptAction { + script: activePageCount-- + } + + ParallelAnimation { + NumberAnimation { + target: launcherList + property: "opacity" + from: 0.0 + to: 1.0 + duration: 300 + } + NumberAnimation { + target: launcherList + property: "scale" + from: 0.0 + to: 1.0 + duration: 300 + } + NumberAnimation { + target: page + property: "x" + from: 0 + to: -page.width + duration: 300 + } + } + + ScriptAction { + script: page.destroy() + } + } + } + } + Rectangle { + id: bar + visible: height > 0 + anchors.bottom: parent.bottom + width: parent.width + height: activePageCount > 0 ? 40 : 0 + + Behavior on height { + NumberAnimation { + duration: 300 + } + } + + Rectangle { + height: 1 + color: "#ccc" + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + } + + Rectangle { + height: 1 + color: "#fff" + anchors.top: parent.top + anchors.topMargin: 1 + anchors.left: parent.left + anchors.right: parent.right + } + + gradient: Gradient { + GradientStop { position: 0 ; color: "#eee" } + GradientStop { position: 1 ; color: "#ccc" } + } + + Image { + id: back + source: "images/back.png" + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: 2 + anchors.left: parent.left + anchors.leftMargin: 16 + + MouseArea { + id: mouse + hoverEnabled: true + anchors.centerIn: parent + width: 38 + height: 31 + anchors.verticalCenterOffset: -1 + enabled: activePageCount > 0 + onClicked: { + pageContainer.children[pageContainer.children.length - 1].exit() + } + Rectangle { + anchors.fill: parent + opacity: mouse.pressed ? 1 : 0 + Behavior on opacity { NumberAnimation{ duration: 100 }} + gradient: Gradient { + GradientStop { position: 0 ; color: "#22000000" } + GradientStop { position: 0.2 ; color: "#11000000" } + } + border.color: "darkgray" + antialiasing: true + radius: 4 + } + } + } + } +} diff --git a/tests/plugins/platforms/webgl/SimpleLauncherDelegate.qml b/tests/plugins/platforms/webgl/SimpleLauncherDelegate.qml new file mode 100644 index 0000000..86a3b0d --- /dev/null +++ b/tests/plugins/platforms/webgl/SimpleLauncherDelegate.qml @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +import QtQuick 2.0 + +Rectangle { + id: container + property Item exampleItem + width: ListView.view.width + height: button.implicitHeight + 22 + + signal clicked() + + gradient: Gradient { + GradientStop { + position: 0 + Behavior on color {ColorAnimation { duration: 100 }} + color: button.pressed ? "#e0e0e0" : "#fff" + } + GradientStop { + position: 1 + Behavior on color {ColorAnimation { duration: 100 }} + color: button.pressed ? "#e0e0e0" : button.containsMouse ? "#f5f5f5" : "#eee" + } + } + + Image { + id: image + opacity: 0.7 + Behavior on opacity {NumberAnimation {duration: 100}} + source: "images/next.png" + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 16 + } + + Item { + id: button + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.right:image.left + implicitHeight: col.height + height: implicitHeight + width: buttonLabel.width + 20 + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: container.clicked() + hoverEnabled: true + } + + Column { + spacing: 2 + id: col + anchors.verticalCenter: parent.verticalCenter + width: parent.width + Text { + id: buttonLabel + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.right: parent.right + anchors.rightMargin: 10 + text: name + color: "black" + font.pixelSize: 22 + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + styleColor: "white" + style: Text.Raised + + } + Text { + id: buttonLabel2 + anchors.left: parent.left + anchors.leftMargin: 10 + text: description + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + color: "#666" + font.pixelSize: 12 + } + } + } + + Rectangle { + height: 1 + color: "#ccc" + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } +} diff --git a/tests/plugins/platforms/webgl/colors.qml b/tests/plugins/platforms/webgl/colors.qml new file mode 100644 index 0000000..88c781d --- /dev/null +++ b/tests/plugins/platforms/webgl/colors.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt WebGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** 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 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** 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.0 + +Rectangle { + property var nextColor: function* () { + while (true) { + yield "red"; + yield "green"; + yield "blue"; + } + } + + MouseArea { + id: mouseArea + property var coroutine: nextColor() + anchors.fill: parent + onClicked: parent.color = coroutine.next().value + } + + Component.onCompleted: mouseArea.clicked(undefined) +} diff --git a/tests/plugins/platforms/webgl/images/back.png b/tests/plugins/platforms/webgl/images/back.png Binary files differnew file mode 100644 index 0000000..5340209 --- /dev/null +++ b/tests/plugins/platforms/webgl/images/back.png diff --git a/tests/plugins/platforms/webgl/images/next.png b/tests/plugins/platforms/webgl/images/next.png Binary files differnew file mode 100644 index 0000000..cdef8db --- /dev/null +++ b/tests/plugins/platforms/webgl/images/next.png diff --git a/tests/plugins/platforms/webgl/launcher.qml b/tests/plugins/platforms/webgl/launcher.qml new file mode 100644 index 0000000..8683267 --- /dev/null +++ b/tests/plugins/platforms/webgl/launcher.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + height: 480 + width: 320 + LauncherList { + id: ll + anchors.fill: parent + Component.onCompleted: { + addExample("Basic", "Simple scene", Qt.resolvedUrl("basic_scene.qml")); + addExample("Colors", "Change the background color in mouse click", + Qt.resolvedUrl("colors.qml")); + } + } +} diff --git a/tests/plugins/platforms/webgl/parameters.h b/tests/plugins/platforms/webgl/parameters.h index 5f07e9e..eaac6e2 100644 --- a/tests/plugins/platforms/webgl/parameters.h +++ b/tests/plugins/platforms/webgl/parameters.h @@ -52,10 +52,10 @@ T readNext(QDataStream &stream, quint32 &offset) template<> QString readNext(QDataStream &stream, quint32 &offset) { - QString value; - stream >> value; - offset += quint32(int(sizeof(qint32)) + value.size()); - return value; + std::vector<char> data(readNext<quint32>(stream, offset)); + stream.readRawData(&data[0], data.size()); + offset += data.size(); + return QString::fromUtf8(data.data(), data.size()); } template<> diff --git a/tests/plugins/platforms/webgl/tst_webgl.cpp b/tests/plugins/platforms/webgl/tst_webgl.cpp index 869e294..d37f130 100644 --- a/tests/plugins/platforms/webgl/tst_webgl.cpp +++ b/tests/plugins/platforms/webgl/tst_webgl.cpp @@ -55,10 +55,60 @@ class tst_WebGL : public QObject { Q_OBJECT + struct GLObject {}; + + struct Buffer : GLObject {}; + struct Shader : GLObject + { + Shader(GLuint type = GL_INVALID_VALUE) : type(type) {} + GLuint type; + QString source; + bool compiled = false; + }; + + struct Program : GLObject + { + QMap<GLuint, Shader *> attached; + bool linked = false; + }; + + struct Texture : GLObject {}; + + struct Context + { + Context(int winId = -1) : winId(winId) {} + + int winId; + Buffer *arrayBuffer = nullptr; + Buffer *elementArrayBuffer = nullptr; + Program *program = nullptr; + }; + + QList<Context> contexts; + QList<Buffer> buffers; + QList<Program> programs; + QList<Shader> shaders; + QList<Texture> textures; + Context *currentContext = nullptr; + QNetworkAccessManager manager; QWebSocket webSocket; QStringList functions; QProcess process; + qintptr websocketPort; + + void connectToQmlScene(); + void sendMouseEvent(Qt::MouseButtons buttons, quint32 x, quint32 y, int winId); + void sendMouseClick(quint32 x, quint32 y, int winId); + + template <typename Struct> + Struct *pointer(const QVariant &id, QList<Struct> &container) + { + const auto handle = id.toInt(); + if (handle > 0 && handle <= container.size()) + return &container[handle - 1]; + return nullptr; + } bool findSwapBuffers(const QSignalSpy &spy); @@ -81,8 +131,56 @@ private slots: void waitForSwapBuffers_data(); void waitForSwapBuffers(); + + void reload_data(); + void reload(); + + void update_data(); + void update(); }; +void tst_WebGL::connectToQmlScene() +{ + const QJsonDocument connectMessage { + QJsonObject { + { QLatin1String("type"), QLatin1String("connect") }, + { QLatin1String("width"), 1920 }, + { QLatin1String("height"), 1080 }, + { QLatin1String("physicalWidth"), 531.3 }, + { QLatin1String("physicalHeight"), 298.9 } + } + }; + + QSignalSpy connected(&webSocket, &QWebSocket::connected); + webSocket.open(QUrl(QString::fromLatin1("ws://localhost:%1").arg(websocketPort))); + QVERIFY(connected.wait()); + webSocket.sendTextMessage(connectMessage.toJson()); + QVERIFY(webSocket.state() == QAbstractSocket::ConnectedState); +} + +void tst_WebGL::sendMouseEvent(Qt::MouseButtons buttons, quint32 x, quint32 y, const int winId) +{ + const QJsonDocument message { + QJsonObject { + { QLatin1String("type"), QLatin1String("mouse") }, + { QLatin1String("buttons"), int(buttons) }, + { QLatin1String("layerX"), int(x) }, + { QLatin1String("layerY"), int(y) }, + { QLatin1String("clientX"), int(x) }, + { QLatin1String("clientY"), int(y) }, + { QLatin1String("time"), QDateTime::currentDateTime().toMSecsSinceEpoch() }, + { QLatin1String("name"), winId } + } + }; + webSocket.sendTextMessage(message.toJson()); +} + +void tst_WebGL::sendMouseClick(quint32 x, quint32 y, int winId) +{ + sendMouseEvent(Qt::LeftButton, x, y, winId); + sendMouseEvent(Qt::NoButton, x, y, winId); +} + bool tst_WebGL::findSwapBuffers(const QSignalSpy &spy) { return std::find_if(spy.cbegin(), spy.cend(), [](const QList<QVariant> &list) { @@ -116,11 +214,13 @@ void tst_WebGL::parseTextMessage(const QString &text) { QString::number(GL_STENCIL_TEST), false }, { QString::number(GL_UNPACK_ALIGNMENT), 4 }, { QString::number(GL_VENDOR), "Qt" }, + { QString::number(GL_VERSION), "WebGL 1.0" }, { QString::number(GL_VIEWPORT), QJsonArray{ 0, 0, 640, 480 } }, { QLatin1String("name"), document["winId"] } }, }; webSocket.sendTextMessage(defaultValuesMessage.toJson()); + contexts.append(Context(document["winId"].toInt())); } } @@ -181,11 +281,104 @@ void tst_WebGL::parseBinaryMessage(const QByteArray &data) offset += sizeof(magic); QCOMPARE(magic, 0xbaadf00d); } + QCOMPARE(int(offset), data.size()); - if (id == -1) + + if (id == -1) { emit command(function, parameters); - else + + if (function == "attachShader") { + const auto shader = pointer(parameters[1], shaders); + QVERIFY(shader); + auto program = pointer(parameters[0], programs); + QVERIFY(program); + program->attached[shader->type] = shader; + } else if (function == "bindBuffer") { + auto buffer = pointer(parameters[1], buffers); + if (parameters[0].toUInt() == GL_ARRAY_BUFFER) + currentContext->arrayBuffer = buffer; + else if (parameters[0].toUInt() == GL_ELEMENT_ARRAY_BUFFER) + currentContext->elementArrayBuffer = buffer; + else + QTest::qFail("Unsupported buffer type", __FILE__, __LINE__); + } else if (function == "compileShader") { + auto shader = pointer(parameters[0], shaders); + QVERIFY(shader); + shader->compiled = true; + } else if (function == "linkProgram") { + auto program = pointer(parameters[0], programs); + QVERIFY(program); + program->linked = true; + } else if (function == "shaderSource") { + auto shader = pointer(parameters[0], shaders); + QVERIFY(shader); + shader->source = parameters[1].toString(); + } else if (function == "makeCurrent") { + currentContext = pointer(parameters[3].toInt(), contexts); + } else if (function == "useProgram") { + currentContext->program = pointer(parameters[0], programs); + } + } else { emit queryCommand(function, id, parameters); + + QJsonValue retval; + static QMap<QString, int> nextIds; + + if (function == "createProgram") { + programs.append(Program{}); + retval = programs.size(); + } else if (function == "createShader") { + shaders.append(Shader(parameters[0].toUInt())); + retval = shaders.size(); + } else if (function == "genBuffers") { + QJsonArray array; + for (int i = 0, count = parameters.first().toInt(); i < count; ++i) { + buffers.append(Buffer{}); + array.append(buffers.size()); + } + retval = array; + } else if (function == "genTextures") { + QJsonArray array; + for (int i = 0, count = parameters.first().toInt(); i < count; ++i) { + textures.append(Texture{}); + array.append(textures.size()); + } + retval = array; + } else if (function == "getError") { + retval = ""; + } else if (function == "getProgramiv") { + const auto program = pointer(parameters[0], programs); + retval = program ? program->linked : false; + } else if (function == "getShaderiv") { + const auto shader = pointer(parameters[0], shaders); + retval = shader ? shader->compiled : false; + } else if (function == "getUniformLocation") { + const auto shaders = currentContext->program->attached[GL_VERTEX_SHADER]->source + + currentContext->program->attached[GL_FRAGMENT_SHADER] ->source; + const QRegularExpression rx(R"rx(uniform +(?:(?:high|medium|low)p +)?\w+ +(\w+) *;)rx"); + auto m = rx.globalMatch(shaders); + for (int i = 0; m.hasNext() && retval.isNull(); ++i) { + if (m.next().captured(1) == parameters[1].toString()) + retval = i; + } + } else if (function == "linkProgram") { + auto program = pointer(parameters[0], programs); + if (program) + program->linked = true; + } else if (function == "swapBuffers") { + // do nothing + } else { + QFAIL("Function not handled"); + } + const QJsonDocument answer { + QJsonObject { + { QLatin1String("type"), QLatin1String("gl_response") }, + { QLatin1String("id"), id }, + { QLatin1String("value"), retval } + } + }; + webSocket.sendTextMessage(answer.toJson()); + } } void tst_WebGL::initTestCase() @@ -197,6 +390,14 @@ void tst_WebGL::initTestCase() void tst_WebGL::init() { QFETCH(QString, scene); + + contexts.clear(); + buffers.clear(); + programs.clear(); + shaders.clear(); + textures.clear(); + currentContext = nullptr; + const auto tryToConnect = [=](quint16 port = PORT) { QTcpSocket socket; socket.connectToHost("localhost", port); @@ -228,15 +429,6 @@ void tst_WebGL::init() }); #endif // defined(QT_DEBUG) QTRY_VERIFY(tryToConnect()); - const QJsonDocument connectMessage { - QJsonObject { - { QLatin1String("type"), QLatin1String("connect") }, - { QLatin1String("width"), 1920 }, - { QLatin1String("height"), 1080 }, - { QLatin1String("physicalWidth"), 531.3 }, - { QLatin1String("physicalHeight"), 298.9 } - } - }; auto reply = manager.get(QNetworkRequest(QUrl("http://localhost:" PORTSTRING "/webqt.js"))); QSignalSpy replyFinishedSpy(reply, &QNetworkReply::finished); @@ -248,14 +440,11 @@ void tst_WebGL::init() const auto match = rx.match(portString); QVERIFY(!match.captured(1).isEmpty()); QVERIFY(match.captured(1).toUInt() <= std::numeric_limits<quint16>::max()); - const auto websocketPort = quint16(match.captured(1).toUInt()); + websocketPort = match.captured(1).toInt(); - QTRY_VERIFY(tryToConnect(websocketPort)); - QSignalSpy connected(&webSocket, &QWebSocket::connected); - webSocket.open(QUrl(QString::fromLatin1("ws://localhost:%1").arg(websocketPort))); - QTRY_VERIFY(!connected.isEmpty()); - webSocket.sendTextMessage(connectMessage.toJson()); - QVERIFY(webSocket.state() == QAbstractSocket::ConnectedState); + QVERIFY(websocketPort != 0); + + connectToQmlScene(); } void tst_WebGL::cleanup() @@ -289,6 +478,48 @@ void tst_WebGL::waitForSwapBuffers() QTRY_VERIFY(findSwapBuffers(spy)); } +void tst_WebGL::reload_data() +{ + QTest::addColumn<QString>("scene"); // Fetched in tst_WebGL::init + QTest::newRow("Basic scene") << QFINDTESTDATA("basic_scene.qml"); + QTest::newRow("Colors") << QFINDTESTDATA("colors.qml");; +} + +void tst_WebGL::reload() +{ + for (int i = 0; i < 2; ++i) { + QSignalSpy spy(this, &tst_WebGL::queryCommand); + QTRY_VERIFY(findSwapBuffers(spy)); + QVERIFY(!QTest::currentTestFailed()); + webSocket.close(); + connectToQmlScene(); + QVERIFY(!QTest::currentTestFailed()); + } +} + +void tst_WebGL::update_data() +{ + QTest::addColumn<QString>("scene"); // Fetched in tst_WebGL::init + QTest::newRow("Colors") << QFINDTESTDATA("colors.qml"); + QTest::newRow("Launcher") << QFINDTESTDATA("launcher.qml"); +} + +void tst_WebGL::update() +{ + { + QSignalSpy spy(this, &tst_WebGL::queryCommand); + QTRY_VERIFY(findSwapBuffers(spy)); + QVERIFY(!QTest::currentTestFailed()); + } + sendMouseClick(0, 0, currentContext->winId); + { + QSignalSpy spy(this, &tst_WebGL::queryCommand); + QEXPECT_FAIL("Launcher", "QWindowPrivate::updateRequestPending is false, no more updates", + Abort); + QTRY_VERIFY(findSwapBuffers(spy)); + } +} + QTEST_MAIN(tst_WebGL) #include "tst_webgl.moc" diff --git a/tests/plugins/platforms/webgl/webgl.pro b/tests/plugins/platforms/webgl/webgl.pro index add4016..36b3c38 100644 --- a/tests/plugins/platforms/webgl/webgl.pro +++ b/tests/plugins/platforms/webgl/webgl.pro @@ -16,4 +16,10 @@ SOURCES += \ TESTDATA = *.qml OTHER_FILES += \ - basic_scene.qml + basic_scene.qml \ + colors.qml \ + images/back.png \ + images/next.png \ + launcher.qml \ + LauncherList.qml \ + SimpleLauncherDelegate.qml |