diff options
author | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-10-20 14:05:58 +0200 |
---|---|---|
committer | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-10-21 18:02:34 +0200 |
commit | 2c8cf8eb42749f6999cc10169c188f9df23738f5 (patch) | |
tree | 4250e84452e10050b815d9dcfb30ce5d7f344ce6 /tests/manual | |
parent | e487b07e18f1cb7ff126744be57b2ae1b9839c6c (diff) |
Fix the workaround in ~QWasmOpenGLContext
The workaround stopped working because JSEvents is now not a global
object. Update the workaround by exporting the JSEvents object from
emscripten runtime and replacing the function that removes the
event handlers to a dummy function that does nothing temporarily, only
to revert it when the context is destroyed.
Fixes: QTBUG-107197
Pick-to: 6.4
Change-Id: Icceae884c85e04fdafcca6cf3c563094d3f6f0dc
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'tests/manual')
-rw-r--r-- | tests/manual/wasm/qstdweb/CMakeLists.txt | 26 | ||||
-rw-r--r-- | tests/manual/wasm/qstdweb/qwasmcompositor_auto.html | 10 | ||||
-rw-r--r-- | tests/manual/wasm/qstdweb/qwasmcompositor_main.cpp | 172 |
3 files changed, 208 insertions, 0 deletions
diff --git a/tests/manual/wasm/qstdweb/CMakeLists.txt b/tests/manual/wasm/qstdweb/CMakeLists.txt index 093fe54663..234b12bab9 100644 --- a/tests/manual/wasm/qstdweb/CMakeLists.txt +++ b/tests/manual/wasm/qstdweb/CMakeLists.txt @@ -44,3 +44,29 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../qtwasmtestlib/qtwasmtestlib.js ${CMAKE_CURRENT_BINARY_DIR}/qtwasmtestlib.js) + +qt_internal_add_manual_test(qwasmcompositor_auto + SOURCES + qwasmcompositor_main.cpp + ../qtwasmtestlib/qtwasmtestlib.cpp + PUBLIC_LIBRARIES + Qt::Core + Qt::CorePrivate + Qt::GuiPrivate +) + +include_directories(../qtwasmtestlib/) + +add_custom_command( + TARGET qwasmcompositor_auto POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/qwasmcompositor_auto.html + ${CMAKE_CURRENT_BINARY_DIR}/qwasmcompositor_auto.html) + +add_custom_command( + TARGET qwasmcompositor_auto POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_SOURCE_DIR}/../qtwasmtestlib/qtwasmtestlib.js + ${CMAKE_CURRENT_BINARY_DIR}/qtwasmtestlib.js) + +target_link_options(qwasmcompositor_auto PRIVATE -sASYNCIFY -Os) diff --git a/tests/manual/wasm/qstdweb/qwasmcompositor_auto.html b/tests/manual/wasm/qstdweb/qwasmcompositor_auto.html new file mode 100644 index 0000000000..26daecdf41 --- /dev/null +++ b/tests/manual/wasm/qstdweb/qwasmcompositor_auto.html @@ -0,0 +1,10 @@ +<!doctype html> +<script type="text/javascript" src="qtwasmtestlib.js"></script> +<script type="text/javascript" src="qwasmcompositor_auto.js"></script> +<script> + window.onload = () => { + runTestCase(document.getElementById("log")); + }; +</script> +<p>Running files auto test.</p> +<div id="log"></div> diff --git a/tests/manual/wasm/qstdweb/qwasmcompositor_main.cpp b/tests/manual/wasm/qstdweb/qwasmcompositor_main.cpp new file mode 100644 index 0000000000..17ab7a90e8 --- /dev/null +++ b/tests/manual/wasm/qstdweb/qwasmcompositor_main.cpp @@ -0,0 +1,172 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtCore/QEvent> +#include <QtCore/QObject> +#include <QtGui/qwindow.h> +#include <QtGui/qguiapplication.h> +#include <QtGui/qoffscreensurface.h> +#include <QtGui/qpa/qwindowsysteminterface.h> +#include <QtGui/private/qrhigles2_p.h> + +#include <qtwasmtestlib.h> + +#include <emscripten.h> +#include <emscripten/val.h> + +#include <functional> +#include <memory> +#include <vector> + +namespace tst_qwasmcompositor_internal { +namespace { +class Window : public QWindow +{ + Q_OBJECT +public: + Window(); + ~Window() override { qDebug() << "dtor Window"; } + + void keyPressEvent(QKeyEvent *) final; + +signals: + void exposed(); + void keyEventReceived(); + void initFailed(); + +protected: +private: + void init(); + + void exposeEvent(QExposeEvent *) override; + bool m_exposedOnce = false; + + std::unique_ptr<QOffscreenSurface> m_fallbackSurface; + std::unique_ptr<QRhi> m_rhi; +}; + +Window::Window() +{ + setSurfaceType(OpenGLSurface); +} + +void Window::exposeEvent(QExposeEvent *) +{ + if (isExposed() && !m_exposedOnce) { + m_exposedOnce = true; + init(); + emit exposed(); + } +} + +void Window::keyPressEvent(QKeyEvent *) +{ + emit keyEventReceived(); +} + +void Window::init() +{ + QRhi::Flags rhiFlags = QRhi::EnableDebugMarkers | QRhi::EnableProfiling; + + m_fallbackSurface.reset(QRhiGles2InitParams::newFallbackSurface()); + QRhiGles2InitParams params; + params.fallbackSurface = m_fallbackSurface.get(); + params.window = this; + + // Double init of RHI causes the OpenGL context to be destroyed, which causes a bug with input. + m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags)); + m_rhi.reset(QRhi::create(QRhi::OpenGLES2, ¶ms, rhiFlags)); + + if (!m_rhi) + emit initFailed(); +} + +} // namespace +} // namespace tst_qwasmcompositor_internal + +using namespace emscripten; + +class QWasmCompositorTest : public QObject +{ + Q_OBJECT + +public: + QWasmCompositorTest() : m_window(val::global("window")), m_testSupport(val::object()) + { + m_window.set("testSupport", m_testSupport); + m_testSupport.set("qtAddContainerElement", + emscripten::val::module_property("qtAddContainerElement")); + m_testSupport.set("qtRemoveContainerElement", + emscripten::val::module_property("qtRemoveContainerElement")); + } + + ~QWasmCompositorTest() noexcept + { + qDebug() << this << "In dtor"; + for (auto it = m_cleanup.rbegin(); it != m_cleanup.rend(); ++it) + (*it)(); + m_window.set("testSupport", emscripten::val::undefined()); + } + +private: + void init() + { + EM_ASM({ + const canvas = document.createElement("canvas"); + canvas.id = "test-canvas-qwasmcompositor"; + testSupport.canvas = canvas; + document.body.appendChild(canvas); + }); + m_cleanup.emplace_back([]() mutable { + EM_ASM({ + testSupport.qtRemoveContainerElement(testSupport.canvas); + testSupport.canvas.parentElement.removeChild(testSupport.canvas); + }); + }); + + EM_ASM({ testSupport.qtAddContainerElement(testSupport.canvas); }); + } + + template<class T> + T *Own(T *plainPtr) + { + m_cleanup.emplace_back([plainPtr]() mutable { delete plainPtr; }); + return plainPtr; + } + + val m_window; + val m_testSupport; + + std::vector<std::function<void()>> m_cleanup; + +private slots: + void testReceivingKeyboardEventsAfterOpenGLContextReset(); +}; + +void QWasmCompositorTest::testReceivingKeyboardEventsAfterOpenGLContextReset() +{ + init(); + + using Window = tst_qwasmcompositor_internal::Window; + Window *window = Own(new Window); + window->show(); + window->requestActivate(); + + QWindowSystemInterface::flushWindowSystemEvents(); + + QObject::connect(window, &Window::keyEventReceived, []() { QWASMSUCCESS(); }); + QObject::connect(window, &Window::initFailed, + []() { QWASMFAIL("Cannot initialize test window"); }); + QObject::connect(window, &Window::exposed, []() { + EM_ASM({ testSupport.canvas.dispatchEvent(new KeyboardEvent('keydown', { key : 'a' })); }); + }); +} + +int main(int argc, char **argv) +{ + auto testObject = std::make_shared<QWasmCompositorTest>(); + QtWasmTest::initTestCase<QGuiApplication>(argc, argv, testObject); + return 0; +} + +#include "qwasmcompositor_main.moc" |